88 changed files with 7477 additions and 0 deletions
@ -0,0 +1,398 @@
@@ -0,0 +1,398 @@
|
||||
// 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); |
||||
SDTask 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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// 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 class RunAllTestsInPadCommand : RunTestInPadCommand |
||||
{ |
||||
public RunAllTestsInPadCommand() |
||||
{ |
||||
} |
||||
|
||||
public RunAllTestsInPadCommand(IRunTestCommandContext context) |
||||
: base(context) |
||||
{ |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
// To make sure all tests are run we set the Owner to null.
|
||||
Owner = null; |
||||
base.Run(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,546 @@
@@ -0,0 +1,546 @@
|
||||
// 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 ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Commands; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Project.Commands; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public abstract class AbstractRunTestCommand : AbstractMenuCommand |
||||
{ |
||||
static MessageViewCategory testRunnerCategory; |
||||
static AbstractRunTestCommand runningTestCommand; |
||||
List<IProject> projects; |
||||
IProject currentProject; |
||||
TestResultsMonitor testResultsMonitor; |
||||
|
||||
public AbstractRunTestCommand() |
||||
{ |
||||
testResultsMonitor = new TestResultsMonitor(); |
||||
testResultsMonitor.TestFinished += TestFinished; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the running test command.
|
||||
/// </summary>
|
||||
public static AbstractRunTestCommand RunningTestCommand { |
||||
get { |
||||
return runningTestCommand; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether a test is currently running.
|
||||
/// </summary>
|
||||
public static bool IsRunningTest { |
||||
get { |
||||
return runningTestCommand != null; |
||||
} |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
projects = new List<IProject>(); |
||||
|
||||
IMember m = TestableCondition.GetMember(Owner); |
||||
IClass c = (m != null) ? m.DeclaringType : TestableCondition.GetClass(Owner); |
||||
IProject project = TestableCondition.GetProject(Owner); |
||||
string namespaceFilter = TestableCondition.GetNamespace(Owner); |
||||
|
||||
if (project != null) { |
||||
projects.Add(project); |
||||
} else if (UnitTestsPad.Instance != null) { |
||||
projects.AddRange(UnitTestsPad.Instance.TestTreeView.GetProjects()); |
||||
} |
||||
|
||||
if (projects.Count > 0) { |
||||
runningTestCommand = this; |
||||
try { |
||||
BeforeRun(); |
||||
if (IsRunningTest) { |
||||
currentProject = projects[0]; |
||||
Run(currentProject, namespaceFilter, c, m); |
||||
} |
||||
} catch { |
||||
runningTestCommand = null; |
||||
throw; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public static MessageViewCategory TestRunnerCategory { |
||||
get { |
||||
if (testRunnerCategory == null) { |
||||
MessageViewCategory.Create(ref testRunnerCategory, "UnitTesting", "${res:ICSharpCode.NUnitPad.NUnitPadContent.PadName}"); |
||||
} |
||||
return testRunnerCategory; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stops running the tests.
|
||||
/// </summary>
|
||||
public void Stop() |
||||
{ |
||||
runningTestCommand = null; |
||||
UpdateUnitTestsPadToolbar(); |
||||
|
||||
projects.Clear(); |
||||
|
||||
testResultsMonitor.Stop(); |
||||
StopMonitoring(); |
||||
|
||||
OnStop(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called before all tests are run. If multiple projects are
|
||||
/// to be tested this is called only once.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeRunTests() |
||||
{ |
||||
} |
||||
|
||||
/// <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() |
||||
{ |
||||
} |
||||
|
||||
protected abstract void RunTests(UnitTestApplicationStartHelper helper); |
||||
|
||||
/// <summary>
|
||||
/// Called by derived classes when a single test run
|
||||
/// is finished.
|
||||
/// </summary>
|
||||
protected void TestsFinished() |
||||
{ |
||||
WorkbenchSingleton.AssertMainThread(); |
||||
|
||||
// Read the rest of the file just in case.
|
||||
testResultsMonitor.Stop(); |
||||
testResultsMonitor.Read(); |
||||
StopMonitoring(); |
||||
|
||||
projects.Remove(currentProject); |
||||
if (projects.Count > 0) { |
||||
currentProject = projects[0]; |
||||
Run(currentProject, null, null, null); |
||||
} else { |
||||
runningTestCommand = null; |
||||
UpdateUnitTestsPadToolbar(); |
||||
if (TaskService.SomethingWentWrong && ErrorListPad.ShowAfterBuild) { |
||||
ShowErrorList(); |
||||
} |
||||
OnAfterRunTests(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called by derived classes to show a single test result.
|
||||
/// </summary>
|
||||
protected void ShowResult(TestResult result) |
||||
{ |
||||
if (result.IsFailure || result.IsIgnored) { |
||||
TaskService.Add(CreateTask(result)); |
||||
} |
||||
UpdateTestResult(result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called when the test run should be stopped.
|
||||
/// </summary>
|
||||
protected virtual void OnStop() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Brings the specified pad to the front.
|
||||
/// </summary>
|
||||
protected void ShowPad(PadDescriptor padDescriptor) |
||||
{ |
||||
if (padDescriptor != null) { |
||||
WorkbenchSingleton.SafeThreadAsyncCall(padDescriptor.BringPadToFront); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the tests after building the project under test.
|
||||
/// </summary>
|
||||
void Run(IProject project, string namespaceFilter, IClass fixture, IMember test) |
||||
{ |
||||
BuildProjectBeforeTestRun build = new BuildProjectBeforeTestRun(project); |
||||
build.BuildComplete += delegate { |
||||
OnBuildComplete(build.LastBuildResults, project, namespaceFilter, fixture, test); |
||||
}; |
||||
build.Run(); |
||||
} |
||||
|
||||
void ShowUnitTestsPad() |
||||
{ |
||||
ShowPad(WorkbenchSingleton.Workbench.GetPad(typeof(UnitTestsPad))); |
||||
} |
||||
|
||||
void UpdateUnitTestsPadToolbar() |
||||
{ |
||||
if (UnitTestsPad.Instance != null) { |
||||
UnitTestsPad.Instance.UpdateToolbar(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets the initial workbench state before starting
|
||||
/// a test run.
|
||||
/// </summary>
|
||||
void BeforeRun() |
||||
{ |
||||
TaskService.BuildMessageViewCategory.ClearText(); |
||||
TaskService.InUpdate = true; |
||||
TaskService.ClearExceptCommentTasks(); |
||||
TaskService.InUpdate = false; |
||||
|
||||
TestRunnerCategory.ClearText(); |
||||
|
||||
ShowUnitTestsPad(); |
||||
ShowOutputPad(); |
||||
|
||||
UpdateUnitTestsPadToolbar(); |
||||
ResetAllTestResults(); |
||||
|
||||
OnBeforeRunTests(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Brings output pad to the front.
|
||||
/// </summary>
|
||||
void ShowOutputPad() |
||||
{ |
||||
ShowPad(WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView))); |
||||
} |
||||
|
||||
Task CreateTask(TestResult result) |
||||
{ |
||||
TaskType taskType = TaskType.Warning; |
||||
FileLineReference lineRef = null; |
||||
string message = String.Empty; |
||||
|
||||
if (result.IsFailure) { |
||||
taskType = TaskType.Error; |
||||
lineRef = OutputTextLineParser.GetNUnitOutputFileLineReference(result.StackTrace, true); |
||||
message = GetTestResultMessage(result, "${res:NUnitPad.NUnitPadContent.TestTreeView.TestFailedMessage}"); |
||||
} else if (result.IsIgnored) { |
||||
message = GetTestResultMessage(result, "${res:NUnitPad.NUnitPadContent.TestTreeView.TestNotExecutedMessage}"); |
||||
} |
||||
if (lineRef == null) { |
||||
lineRef = FindTest(result.Name); |
||||
} |
||||
if (lineRef != null) { |
||||
return new Task(FileName.Create(lineRef.FileName), |
||||
message, lineRef.Column, lineRef.Line, taskType); |
||||
} |
||||
return new Task(null, message, 0, 0, taskType); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the test result message if there is on otherwise
|
||||
/// uses the string resource to create a message.
|
||||
/// </summary>
|
||||
string GetTestResultMessage(TestResult result, string stringResource) |
||||
{ |
||||
if (result.Message.Length > 0) { |
||||
return result.Message; |
||||
} |
||||
return StringParser.Parse(stringResource, new string[,] {{"TestCase", result.Name}}); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the location of the specified test method in the
|
||||
/// project being tested.
|
||||
/// </summary>
|
||||
FileLineReference FindTest(string methodName) |
||||
{ |
||||
TestProject testProject = GetTestProject(currentProject); |
||||
if (testProject != null) { |
||||
TestMethod method = testProject.TestClasses.GetTestMethod(methodName); |
||||
if (method != null) { |
||||
MemberResolveResult resolveResult = new MemberResolveResult(null, null, method.Method); |
||||
FilePosition filePos = resolveResult.GetDefinitionPosition(); |
||||
return new FileLineReference(filePos.FileName, filePos.Line, filePos.Column); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void ShowErrorList() |
||||
{ |
||||
ShowPad(WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad))); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the test for the project after a successful build.
|
||||
/// </summary>
|
||||
void OnBuildComplete(BuildResults results, IProject project, string namespaceFilter, IClass fixture, IMember test) |
||||
{ |
||||
if (results.ErrorCount == 0 && IsRunningTest) { |
||||
UnitTestApplicationStartHelper helper = new UnitTestApplicationStartHelper(); |
||||
|
||||
UnitTestingOptions options = new UnitTestingOptions(); |
||||
helper.NoThread = options.NoThread; |
||||
helper.NoLogo = options.NoLogo; |
||||
helper.NoDots = options.NoDots; |
||||
helper.Labels = options.Labels; |
||||
helper.ShadowCopy = !options.NoShadow; |
||||
|
||||
if (options.CreateXmlOutputFile) { |
||||
helper.XmlOutputFile = Path.Combine(Path.GetDirectoryName(project.OutputAssemblyFullPath), project.AssemblyName + "-TestResult.xml"); |
||||
} |
||||
|
||||
helper.Initialize(project, namespaceFilter, fixture, test); |
||||
helper.Results = Path.GetTempFileName(); |
||||
|
||||
ResetTestResults(project); |
||||
|
||||
testResultsMonitor.FileName = helper.Results; |
||||
testResultsMonitor.Start(); |
||||
|
||||
try { |
||||
RunTests(helper); |
||||
} catch { |
||||
StopMonitoring(); |
||||
throw; |
||||
} |
||||
} else { |
||||
if (IsRunningTest) { |
||||
Stop(); |
||||
} |
||||
if (TaskService.SomethingWentWrong && ErrorListPad.ShowAfterBuild) { |
||||
ShowErrorList(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears the test results in the test tree view for the
|
||||
/// project currently being tested.
|
||||
/// </summary>
|
||||
void ResetTestResults(IProject project) |
||||
{ |
||||
TestProject testProject = GetTestProject(project); |
||||
if (testProject != null) { |
||||
testProject.ResetTestResults(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears the test results in the test tree view for all the
|
||||
/// displayed projects.
|
||||
/// </summary>
|
||||
void ResetAllTestResults() |
||||
{ |
||||
if (UnitTestsPad.Instance != null) { |
||||
UnitTestsPad.Instance.TestTreeView.ResetTestResults(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the TestProject associated with the specified project
|
||||
/// from the test tree view.
|
||||
/// </summary>
|
||||
TestProject GetTestProject(IProject project) |
||||
{ |
||||
if (UnitTestsPad.Instance != null) { |
||||
return UnitTestsPad.Instance.TestTreeView.GetTestProject(project); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test result in the test tree view.
|
||||
/// </summary>
|
||||
void UpdateTestResult(TestResult result) |
||||
{ |
||||
TestProject testProject = GetTestProject(currentProject); |
||||
if (testProject != null) { |
||||
testProject.UpdateTestResult(result); |
||||
} |
||||
} |
||||
|
||||
void StopMonitoring() |
||||
{ |
||||
try { |
||||
File.Delete(testResultsMonitor.FileName); |
||||
} catch { } |
||||
|
||||
testResultsMonitor.Dispose(); |
||||
} |
||||
|
||||
void TestFinished(object source, TestFinishedEventArgs e) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(ShowResult, e.Result); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Custom build command that makes sure errors and warnings
|
||||
/// are not cleared from the Errors list before every build since
|
||||
/// we may be running multiple tests after each other.
|
||||
/// </summary>
|
||||
public class BuildProjectBeforeTestRun : BuildProjectBeforeExecute |
||||
{ |
||||
public BuildProjectBeforeTestRun(IProject targetProject) |
||||
: base(targetProject) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Before a build do not clear the tasks, just save any
|
||||
/// dirty files.
|
||||
/// </summary>
|
||||
public override void BeforeBuild() |
||||
{ |
||||
SaveAllFiles.SaveAll(); |
||||
} |
||||
} |
||||
|
||||
public class RunTestInPadCommand : AbstractRunTestCommand |
||||
{ |
||||
ProcessRunner runner; |
||||
|
||||
public RunTestInPadCommand() |
||||
{ |
||||
runner = new ProcessRunner(); |
||||
runner.LogStandardOutputAndError = false; |
||||
runner.OutputLineReceived += OutputLineReceived; |
||||
runner.ProcessExited += ProcessExited; |
||||
} |
||||
|
||||
protected override void RunTests(UnitTestApplicationStartHelper helper) |
||||
{ |
||||
TestRunnerCategory.AppendLine(helper.GetCommandLine()); |
||||
runner.Start(helper.UnitTestApplication, helper.GetArguments()); |
||||
} |
||||
|
||||
protected override void OnStop() |
||||
{ |
||||
runner.Kill(); |
||||
} |
||||
|
||||
protected ProcessRunner GetProcessRunner() |
||||
{ |
||||
return runner; |
||||
} |
||||
|
||||
void OutputLineReceived(object source, LineReceivedEventArgs e) |
||||
{ |
||||
TestRunnerCategory.AppendLine(e.Line); |
||||
} |
||||
|
||||
void ProcessExited(object source, EventArgs e) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(TestsFinished); |
||||
} |
||||
|
||||
void TestFinished(object source, TestFinishedEventArgs e) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(ShowResult, e.Result); |
||||
} |
||||
} |
||||
|
||||
public class RunTestWithDebuggerCommand : AbstractRunTestCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
if (DebuggerService.IsDebuggerLoaded && DebuggerService.CurrentDebugger.IsDebugging) { |
||||
if (MessageService.AskQuestion("${res:XML.MainMenu.RunMenu.Compile.StopDebuggingQuestion}", |
||||
"${res:XML.MainMenu.RunMenu.Compile.StopDebuggingTitle}")) |
||||
{ |
||||
DebuggerService.CurrentDebugger.Stop(); |
||||
base.Run(); |
||||
} |
||||
} else { |
||||
base.Run(); |
||||
} |
||||
} |
||||
|
||||
protected override void RunTests(UnitTestApplicationStartHelper helper) |
||||
{ |
||||
bool running = false; |
||||
|
||||
try { |
||||
TestRunnerCategory.AppendLine(helper.GetCommandLine()); |
||||
ProcessStartInfo startInfo = new ProcessStartInfo(helper.UnitTestApplication); |
||||
startInfo.Arguments = helper.GetArguments(); |
||||
startInfo.WorkingDirectory = UnitTestApplicationStartHelper.UnitTestApplicationDirectory; |
||||
DebuggerService.DebugStopped += DebuggerFinished; |
||||
DebuggerService.CurrentDebugger.Start(startInfo); |
||||
running = true; |
||||
} finally { |
||||
if (!running) { |
||||
DebuggerService.DebugStopped -= DebuggerFinished; |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected override void OnStop() |
||||
{ |
||||
if (DebuggerService.CurrentDebugger.IsDebugging) { |
||||
DebuggerService.CurrentDebugger.Stop(); |
||||
} |
||||
} |
||||
|
||||
void DebuggerFinished(object sender, EventArgs e) |
||||
{ |
||||
DebuggerService.DebugStopped -= DebuggerFinished; |
||||
WorkbenchSingleton.SafeThreadAsyncCall(TestsFinished); |
||||
} |
||||
} |
||||
|
||||
public class RunAllTestsInPadCommand : RunTestInPadCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
// To make sure all tests are run we set the Owner to null.
|
||||
Owner = null; |
||||
base.Run(); |
||||
} |
||||
} |
||||
|
||||
public class RunProjectTestsInPadCommand : RunTestInPadCommand, ITestTreeView |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
Owner = this; |
||||
base.Run(); |
||||
} |
||||
|
||||
public IMember SelectedMethod { |
||||
get { return null; } |
||||
} |
||||
|
||||
public IClass SelectedClass { |
||||
get { return null; } |
||||
} |
||||
|
||||
public IProject SelectedProject { |
||||
get { return ProjectService.CurrentProject; } |
||||
} |
||||
|
||||
public string SelectedNamespace { |
||||
get { return null; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// 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; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RunTestInPadCommand : AbstractRunTestCommand |
||||
{ |
||||
public RunTestInPadCommand() |
||||
{ |
||||
} |
||||
|
||||
public RunTestInPadCommand(IRunTestCommandContext context) |
||||
: base(context) |
||||
{ |
||||
} |
||||
|
||||
protected override ITestRunner CreateTestRunner(IProject project) |
||||
{ |
||||
return Context.RegisteredTestFrameworks.CreateTestRunner(project); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
// 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.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RunTestWithDebuggerCommand : AbstractRunTestCommand |
||||
{ |
||||
public RunTestWithDebuggerCommand() |
||||
{ |
||||
} |
||||
|
||||
public RunTestWithDebuggerCommand(IRunTestCommandContext context) |
||||
: base(context) |
||||
{ |
||||
} |
||||
|
||||
protected override ITestRunner CreateTestRunner(IProject project) |
||||
{ |
||||
return Context.RegisteredTestFrameworks.CreateTestDebugger(project); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// 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 ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class EmptyUnitTestsPad : IUnitTestsPad |
||||
{ |
||||
Solution solution; |
||||
|
||||
public EmptyUnitTestsPad() |
||||
: this(null) |
||||
{ |
||||
} |
||||
|
||||
public EmptyUnitTestsPad(Solution solution) |
||||
{ |
||||
this.solution = solution; |
||||
} |
||||
|
||||
public void UpdateToolbar() |
||||
{ |
||||
} |
||||
|
||||
public void BringToFront() |
||||
{ |
||||
} |
||||
|
||||
public void ResetTestResults() |
||||
{ |
||||
} |
||||
|
||||
public IProject[] GetProjects() |
||||
{ |
||||
if (solution != null) { |
||||
return solution.Projects.ToArray(); |
||||
} |
||||
return new IProject[0]; |
||||
} |
||||
|
||||
public TestProject GetTestProject(IProject project) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
public void CollapseAll() |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
<gui:OptionPanel x:Class="ICSharpCode.UnitTesting.UnitTestingOptionsPanel" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:local="clr-namespace:ICSharpCode.UnitTesting" |
||||
xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui;assembly=ICSharpCode.SharpDevelop" |
||||
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets" |
||||
xmlns:sd="http://icsharpcode.net/sharpdevelop/core" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<gui:OptionPanel.Resources> |
||||
<sd:NotBoolConverter x:Key="negator" /> |
||||
</gui:OptionPanel.Resources> |
||||
<GroupBox Header="{sd:Localize ICSharpCode.NUnitPad.NUnitPadContent.PadName}"> |
||||
<widgets:StackPanelWithSpacing SpaceBetweenItems="5"> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.Labels}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.LabelEachTest}" /> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.NoLogo, Converter={StaticResource negator}}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.ShowLogo}" /> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.NoDots, Converter={StaticResource negator}}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.ShowProgress}" /> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.NoShadow, Converter={StaticResource negator}}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.ShadowCopy}" /> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.NoThread, Converter={StaticResource negator}}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.Thread}" /> |
||||
<CheckBox |
||||
IsChecked="{sd:OptionBinding local:UnitTestingOptions.CreateXmlOutputFile}" |
||||
Content="{sd:Localize ICSharpCode.UnitTesting.OptionsPanel.CreateXmlOutputFile}" /> |
||||
</widgets:StackPanelWithSpacing> |
||||
</GroupBox> |
||||
</gui:OptionPanel> |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// 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; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public partial class UnitTestingOptionsPanel : OptionPanel |
||||
{ |
||||
public UnitTestingOptionsPanel() |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,348 @@
@@ -0,0 +1,348 @@
|
||||
// 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 System.Windows.Controls; |
||||
using System.Windows.Media.Imaging; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.Core.Presentation; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Parser; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestsPad : AbstractPadContent |
||||
{ |
||||
SharpTreeView treeView; |
||||
bool disposed; |
||||
DockPanel panel; |
||||
ToolBar toolBar; |
||||
List<Tuple<IParsedFile, IParsedFile>> pending = new List<Tuple<IParsedFile, IParsedFile>>(); |
||||
static UnitTestsPad instance; |
||||
|
||||
public UnitTestsPad() |
||||
: this(TestService.RegisteredTestFrameworks) |
||||
{ |
||||
} |
||||
|
||||
public UnitTestsPad(IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
instance = this; |
||||
|
||||
panel = new DockPanel(); |
||||
|
||||
toolBar = CreateToolBar("/SharpDevelop/Pads/UnitTestsPad/Toolbar"); |
||||
panel.Children.Add(toolBar); |
||||
DockPanel.SetDock(toolBar, Dock.Top); |
||||
|
||||
treeView = new SharpTreeView(); |
||||
treeView.MouseDoubleClick += TestTreeViewDoubleClick; |
||||
// treeView.KeyDown += TestTreeViewKeyPress;
|
||||
panel.Children.Add(treeView); |
||||
|
||||
// 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.ContextMenu = 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; |
||||
|
||||
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(toolBar);
|
||||
} |
||||
|
||||
/// <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.Root = new RootUnitTestNode(solution); |
||||
} else { |
||||
treeView.Root = null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <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) |
||||
{ |
||||
SolutionLoaded(GetOpenSolution()); |
||||
} |
||||
|
||||
/// <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(IParsedFile oldFile, IParsedFile newFile) |
||||
{ |
||||
RootUnitTestNode root = (RootUnitTestNode)treeView.Root; |
||||
if (root == null) { |
||||
SolutionLoaded(GetOpenSolution()); |
||||
root = (RootUnitTestNode)treeView.Root; |
||||
if (root == null) return; |
||||
} |
||||
var solution = GetOpenSolution(); |
||||
if (solution == null) |
||||
return; |
||||
var project = solution.FindProjectContainingFile((oldFile ?? newFile).FileName); |
||||
if (project == null) |
||||
return; |
||||
var projectNode = root.Children.OfType<ProjectUnitTestNode>().FirstOrDefault(node => node.Project == project); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Virtual method so we can override this method and return
|
||||
/// a dummy ToolBar when testing.
|
||||
/// </summary>
|
||||
protected virtual ToolBar CreateToolBar(string name) |
||||
{ |
||||
return ToolBarService.CreateToolBar(treeView, treeView, name); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Virtual method so we can override this method and return
|
||||
/// a dummy ContextMenu when testing.
|
||||
/// </summary>
|
||||
protected virtual ContextMenu 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 SharpTreeView CreateTestTreeView(IRegisteredTestFrameworks testFrameworks)
|
||||
// {
|
||||
// return new SharpTreeView();
|
||||
// }
|
||||
|
||||
/// <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) { |
||||
var files = Tuple.Create(e.OldParsedFile, e.NewParsedFile); |
||||
pending.Add(files); |
||||
} |
||||
WorkbenchSingleton.SafeThreadAsyncCall(UpdateParseInfo); |
||||
} |
||||
|
||||
void UpdateParseInfo() |
||||
{ |
||||
lock (pending) { |
||||
foreach (var files in pending) { |
||||
UpdateParseInfo(files.Item1, files.Item2); |
||||
} |
||||
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);
|
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// 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.Core; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestAddInTree : IAddInTree |
||||
{ |
||||
public List<T> BuildItems<T>(string path, object caller) |
||||
{ |
||||
return AddInTree.BuildItems<T>(path, caller); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// 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 class UnitTestBuildOptions : IBuildOptions |
||||
{ |
||||
public bool ShowErrorListAfterBuild { |
||||
get { return BuildOptions.ShowErrorListAfterBuild; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// 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 class UnitTestBuildProjectFactory : IBuildProjectFactory |
||||
{ |
||||
public BuildProject CreateBuildProjectBeforeTestRun(IEnumerable<IProject> projects) |
||||
{ |
||||
return new BuildProjectBeforeExecute(new MultipleProjectBuildable(projects)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
// 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.Debugging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestDebuggerService : IUnitTestDebuggerService |
||||
{ |
||||
public bool IsDebuggerLoaded { |
||||
get { return DebuggerService.IsDebuggerLoaded; } |
||||
} |
||||
|
||||
public IDebugger CurrentDebugger { |
||||
get { return DebuggerService.CurrentDebugger; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
// 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; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestFileService : IUnitTestFileService |
||||
{ |
||||
public void OpenFile(string fileName) |
||||
{ |
||||
FileService.OpenFile(fileName); |
||||
} |
||||
|
||||
public void JumpToFilePosition(string fileName, int line, int column) |
||||
{ |
||||
FileService.JumpToFilePosition(fileName, line, column); |
||||
} |
||||
|
||||
public bool FileExists(string fileName) |
||||
{ |
||||
return File.Exists(fileName); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// 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 class UnitTestSaveAllFilesCommand : IUnitTestSaveAllFilesCommand |
||||
{ |
||||
public void SaveAllFiles() |
||||
{ |
||||
ICSharpCode.SharpDevelop.Commands.SaveAllFiles.SaveAll(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
// 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(SDTask task) |
||||
{ |
||||
TaskService.Add(task); |
||||
} |
||||
|
||||
public bool SomethingWentWrong { |
||||
get { return TaskService.SomethingWentWrong; } |
||||
} |
||||
|
||||
public bool HasCriticalErrors(bool treatWarningsAsErrors) |
||||
{ |
||||
return TaskService.HasCriticalErrors(treatWarningsAsErrors); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
// 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 UnitTestWorkbench : IUnitTestWorkbench |
||||
{ |
||||
public PadDescriptor GetPad(Type type) |
||||
{ |
||||
return WorkbenchSingleton.Workbench.GetPad(type); |
||||
} |
||||
|
||||
public void SafeThreadAsyncCall(Action method) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(method); |
||||
} |
||||
|
||||
public void SafeThreadAsyncCall<A>(Action<A> method, A arg1) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(method, arg1); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
// 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; } |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IRegisteredTestFrameworks |
||||
{ |
||||
ITestFramework GetTestFrameworkForProject(IProject project); |
||||
ITestRunner CreateTestRunner(IProject project); |
||||
ITestRunner CreateTestDebugger(IProject project); |
||||
|
||||
bool IsTestMember(IUnresolvedMember member); |
||||
bool IsTestClass(IUnresolvedTypeDefinition typeDefinition); |
||||
bool IsTestProject(IProject project); |
||||
|
||||
IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition typeDefinition); |
||||
|
||||
bool IsBuildNeededBeforeTestRunForProject(IProject project); |
||||
} |
||||
} |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
// 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.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; } |
||||
IMessageService MessageService { get; } |
||||
IUnitTestSaveAllFilesCommand SaveAllFilesCommand { get; } |
||||
IStatusBarService StatusBarService { get; } |
||||
Solution OpenSolution { get; } |
||||
} |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface ITestFramework |
||||
{ |
||||
bool IsTestMember(IUnresolvedMember member); |
||||
bool IsTestClass(IUnresolvedTypeDefinition c); |
||||
bool IsTestProject(IProject project); |
||||
|
||||
IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition typeDefinition); |
||||
|
||||
ITestRunner CreateTestRunner(); |
||||
ITestRunner CreateTestDebugger(); |
||||
|
||||
bool IsBuildNeededBeforeTestRun { get; } |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// 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; } |
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// 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(); |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using System; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface ITestTreeView |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the selected member in the test tree view.
|
||||
/// </summary>
|
||||
IUnresolvedMember SelectedMember {get;} |
||||
|
||||
/// <summary>
|
||||
/// Gets the selected class in the test tree view.
|
||||
/// </summary>
|
||||
IUnresolvedTypeDefinition 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;} |
||||
} |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
// 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.Debugging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestDebuggerService |
||||
{ |
||||
bool IsDebuggerLoaded { get; } |
||||
IDebugger CurrentDebugger { get; } |
||||
} |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
// 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; |
||||
} |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
// 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(); |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// 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(SDTask task); |
||||
bool SomethingWentWrong { get; } |
||||
bool HasCriticalErrors(bool treatWarningsAsErrors); |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// 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); |
||||
} |
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// 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(); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// 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.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// IBuildable implementation that builds several projects.
|
||||
/// </summary>
|
||||
public class MultipleProjectBuildable : IBuildable |
||||
{ |
||||
readonly IBuildable[] projects; |
||||
|
||||
public MultipleProjectBuildable(IEnumerable<IBuildable> projects) |
||||
{ |
||||
this.projects = projects.ToArray(); |
||||
} |
||||
|
||||
public string Name { |
||||
get { return string.Empty; } |
||||
} |
||||
|
||||
public Solution ParentSolution { |
||||
get { return projects.Length > 0 ? projects[0].ParentSolution : null; } |
||||
} |
||||
|
||||
public ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions) |
||||
{ |
||||
return projects; |
||||
} |
||||
|
||||
public void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink) |
||||
{ |
||||
// SharpDevelop already has built our dependencies, so we're done immediately.
|
||||
feedbackSink.Done(true); |
||||
} |
||||
|
||||
public ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable) |
||||
{ |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,249 @@
@@ -0,0 +1,249 @@
|
||||
// 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.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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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(), |
||||
UnitTestingOptions.Instance.Clone()) |
||||
{ |
||||
} |
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
// 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.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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
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; |
||||
} |
||||
} |
||||
|
||||
DomRegion CreateFilePosition(FileLineReference fileLineRef) |
||||
{ |
||||
string fileName = Path.GetFullPath(fileLineRef.FileName); |
||||
return new FilePosition(fileName, fileLineRef.Line, fileLineRef.Column + 1); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
// 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(), |
||||
UnitTestingOptions.Instance.Clone()) |
||||
{ |
||||
} |
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
// 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 |
||||
{ |
||||
/// <summary>
|
||||
/// All Tests root tree node that is added to the test tree when the
|
||||
/// solution has multiple test projects.
|
||||
/// </summary>
|
||||
public class AllTestsTreeNode : TestTreeNode |
||||
{ |
||||
public AllTestsTreeNode() |
||||
: base(null, StringParser.Parse("${res:ICSharpCode.UnitTesting.AllTestsTreeNode.Text}")) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Raised when the all tests tree node is disposed.
|
||||
/// </summary>
|
||||
public event EventHandler Disposed; |
||||
|
||||
/// <summary>
|
||||
/// Disposes this tree node.
|
||||
/// </summary>
|
||||
public override void Dispose() |
||||
{ |
||||
base.Dispose(); |
||||
if (Disposed != null) { |
||||
Disposed(this, new EventArgs()); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new project node as a child of the All Tests node.
|
||||
/// </summary>
|
||||
public void AddProjectNode(TestProjectTreeNode node) |
||||
{ |
||||
node.AddTo(this); |
||||
node.ImageIndexChanged += TestProjectTreeNodeImageIndexChanged; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the project node.
|
||||
/// </summary>
|
||||
public void RemoveProjectNode(TestProjectTreeNode node) |
||||
{ |
||||
if (Nodes.Contains(node)) { |
||||
node.ImageIndexChanged -= TestProjectTreeNodeImageIndexChanged; |
||||
node.Remove(); |
||||
} |
||||
} |
||||
|
||||
void TestProjectTreeNodeImageIndexChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets the All Tests image index based on the current image
|
||||
/// indexes of the child project tree nodes.
|
||||
/// </summary>
|
||||
void UpdateImageListIndex() |
||||
{ |
||||
int ignored = 0; |
||||
int failed = 0; |
||||
int passed = 0; |
||||
int notRun = 0; |
||||
int total = Nodes.Count; |
||||
|
||||
foreach (TestProjectTreeNode projectNode in Nodes) { |
||||
switch (projectNode.ImageIndex) { |
||||
case (int)TestTreeViewImageListIndex.TestFailed: |
||||
failed++; |
||||
break; |
||||
case (int)TestTreeViewImageListIndex.TestPassed: |
||||
passed++; |
||||
break; |
||||
case (int)TestTreeViewImageListIndex.TestIgnored: |
||||
ignored++; |
||||
break; |
||||
default: // Not run.
|
||||
notRun++; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Update the image index based on the test project results.
|
||||
if (failed > 0) { |
||||
UpdateImageListIndex(TestResultType.Failure); |
||||
} else if (ignored > 0) { |
||||
UpdateImageListIndex(TestResultType.Ignored); |
||||
} else if (passed > 0 && notRun == 0) { |
||||
UpdateImageListIndex(TestResultType.Success); |
||||
} else { |
||||
UpdateImageListIndex(TestResultType.None); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
// 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.Reflection; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Imaging; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class ProjectUnitTestNode : UnitTestBaseNode |
||||
{ |
||||
TestProject project; |
||||
|
||||
public TestProject Project { |
||||
get { return project; } |
||||
} |
||||
|
||||
public ProjectUnitTestNode(TestProject project) |
||||
{ |
||||
this.project = project; |
||||
project. |
||||
} |
||||
|
||||
protected override void LoadChildren() |
||||
{ |
||||
base.LoadChildren(); |
||||
} |
||||
|
||||
public override object Text { |
||||
get { return project.Name; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
// 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.Reflection; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Imaging; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Parser; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.TreeView; |
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Description of RootUnitTestNode.
|
||||
/// </summary>
|
||||
public class RootUnitTestNode : UnitTestBaseNode |
||||
{ |
||||
Solution solution; |
||||
|
||||
public RootUnitTestNode(Solution solution) |
||||
{ |
||||
this.solution = solution; |
||||
ProjectService.ProjectAdded += OnProjectAdded; |
||||
ProjectService.ProjectRemoved += OnProjectRemoved; |
||||
ParserService.LoadSolutionProjectsThreadEnded += delegate { LoadChildren(); }; |
||||
LazyLoading = true; |
||||
} |
||||
|
||||
void OnProjectRemoved(object sender, ProjectEventArgs e) |
||||
{ |
||||
LoadChildren(); |
||||
} |
||||
|
||||
void OnProjectAdded(object sender, ProjectEventArgs e) |
||||
{ |
||||
LoadChildren(); |
||||
} |
||||
|
||||
protected override void LoadChildren() |
||||
{ |
||||
this.Children.Clear(); |
||||
if (!ParserService.LoadSolutionProjectsThreadRunning) |
||||
this.Children.AddRange(solution.Projects.Where(p => p.IsTestProject()).Select(p => new ProjectUnitTestNode(new TestProject(p)))); |
||||
} |
||||
|
||||
public override object Text { |
||||
get { return ResourceService.GetString("ICSharpCode.UnitTesting.AllTestsTreeNode.Text"); } |
||||
} |
||||
} |
||||
|
||||
public static class Extensions |
||||
{ |
||||
public static bool IsTestProject(this IProject project) |
||||
{ |
||||
if (project == null) |
||||
throw new ArgumentNullException("project"); |
||||
if (project.ProjectContent == null) |
||||
return false; |
||||
return ParserService.GetCompilation(project).FindType(typeof(TestAttribute)).Kind != TypeKind.Unknown; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
// 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>
|
||||
/// 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 itd 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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// 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>
|
||||
/// 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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// 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 method that has the [Test] attribute associated with it.
|
||||
/// </summary>
|
||||
public class TestMethodTreeNode : TestTreeNode |
||||
{ |
||||
TestMethod testMethod; |
||||
|
||||
public TestMethodTreeNode(TestProject project, TestMethod testMethod) |
||||
: base(project, testMethod.Name) |
||||
{ |
||||
this.testMethod = testMethod; |
||||
testMethod.ResultChanged += TestMethodResultChanged; |
||||
UpdateImageListIndex(testMethod.Result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IMethod for this test method.
|
||||
/// </summary>
|
||||
public IMember Method { |
||||
get { |
||||
return testMethod.Method; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the TestMethod.ResultChanged event handler.
|
||||
/// </summary>
|
||||
public override void Dispose() |
||||
{ |
||||
if (!IsDisposed) { |
||||
testMethod.ResultChanged -= TestMethodResultChanged; |
||||
} |
||||
base.Dispose(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the node's icon after the test method result
|
||||
/// has changed.
|
||||
/// </summary>
|
||||
void TestMethodResultChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(testMethod.Result); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,336 @@
@@ -0,0 +1,336 @@
|
||||
// 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.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(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
// 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>
|
||||
/// 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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
// 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; |
||||
using ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for all test tree nodes.
|
||||
/// </summary>
|
||||
public abstract class TestTreeNode : SharpTreeNode |
||||
{ |
||||
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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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 ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public abstract class UnitTestBaseNode : SharpTreeNode |
||||
{ |
||||
internal virtual TestResultType TestResultType { |
||||
get { |
||||
if (Children.Count == 0) return TestResultType.None; |
||||
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.Failure)) |
||||
return TestResultType.Failure; |
||||
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.None)) |
||||
return TestResultType.None; |
||||
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.Ignored)) |
||||
return TestResultType.Ignored; |
||||
return TestResultType.Success; |
||||
} |
||||
} |
||||
public override object Icon { |
||||
get { return GetIcon(TestResultType); } |
||||
} |
||||
|
||||
object GetIcon(TestResultType testResultType) |
||||
{ |
||||
switch (testResultType) { |
||||
case TestResultType.None: |
||||
return Images.Grey; |
||||
case TestResultType.Success: |
||||
return Images.Green; |
||||
case TestResultType.Failure: |
||||
return Images.Red; |
||||
case TestResultType.Ignored: |
||||
return Images.Yellow; |
||||
default: |
||||
throw new Exception("Invalid value for TestResultType"); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
// 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 |
||||
{ |
||||
/// <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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
// 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.Media.Imaging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
static class Images |
||||
{ |
||||
static BitmapImage LoadBitmap(string name) |
||||
{ |
||||
BitmapImage image = new BitmapImage(new Uri("pack://application:,,,/UnitTesting;component/Resources/" + name + ".png")); |
||||
image.Freeze(); |
||||
return image; |
||||
} |
||||
|
||||
public static readonly BitmapImage Grey = LoadBitmap("Grey"); |
||||
public static readonly BitmapImage Green = LoadBitmap("Green"); |
||||
public static readonly BitmapImage Red = LoadBitmap("Red"); |
||||
public static readonly BitmapImage Yellow = LoadBitmap("Yellow"); |
||||
} |
||||
} |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
// 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 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; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// 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; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RunTestCommandContext : IRunTestCommandContext |
||||
{ |
||||
UnitTestingOptions options = UnitTestingOptions.Instance.Clone(); |
||||
IRegisteredTestFrameworks testFrameworks = TestService.RegisteredTestFrameworks; |
||||
UnitTestTaskService taskService = new UnitTestTaskService(); |
||||
UnitTestWorkbench workbench = new UnitTestWorkbench(); |
||||
UnitTestBuildProjectFactory buildProjectFactory = new UnitTestBuildProjectFactory(); |
||||
UnitTestBuildOptions buildOptions = new UnitTestBuildOptions(); |
||||
MessageViewCategory unitTestCategory = TestService.UnitTestMessageView; |
||||
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 null; } |
||||
} |
||||
|
||||
public IMessageService MessageService { |
||||
get { return SD.MessageService; } |
||||
} |
||||
|
||||
public IUnitTestSaveAllFilesCommand SaveAllFilesCommand { |
||||
get { return saveAllFilesCommand; } |
||||
} |
||||
|
||||
public IStatusBarService StatusBarService { |
||||
get { return statusBarService; } |
||||
} |
||||
|
||||
public Solution OpenSolution { |
||||
get { return ProjectService.OpenSolution; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
|
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class InnerClassEnumerator : IEnumerable<IClass> |
||||
{ |
||||
readonly IClass _c; |
||||
|
||||
public InnerClassEnumerator(IClass c) |
||||
{ |
||||
_c = c; |
||||
} |
||||
|
||||
#region IEnumerable<IClass> Members
|
||||
|
||||
public IEnumerator<IClass> GetEnumerator() |
||||
{ |
||||
var result = new List<IClass>(); |
||||
Visit(_c, result); |
||||
return result.GetEnumerator(); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||
{ |
||||
return GetEnumerator(); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
private void Visit(IClass c, List<IClass> resultList) |
||||
{ |
||||
foreach (var innerClass in c.InnerClasses) |
||||
{ |
||||
resultList.Add(innerClass); |
||||
Visit(innerClass, resultList); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
// 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 delegate void MessageReceivedEventHandler(object sender, MessageReceivedEventArgs e); |
||||
|
||||
public class MessageReceivedEventArgs : EventArgs |
||||
{ |
||||
string message; |
||||
|
||||
public MessageReceivedEventArgs(string message) |
||||
{ |
||||
this.message = message; |
||||
} |
||||
|
||||
public string Message { |
||||
get { return message; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,116 @@
@@ -0,0 +1,116 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
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(IUnresolvedMember member) |
||||
{ |
||||
ITestFramework testFramework = GetTestFramework(member); |
||||
if (testFramework != null) { |
||||
return testFramework.IsTestMember(member); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition @class) { |
||||
ITestFramework testFramework = GetTestFramework(@class); |
||||
if (testFramework != null) |
||||
return testFramework.GetTestMembersFor(@class); |
||||
return new IUnresolvedMember[0]; |
||||
} |
||||
|
||||
ITestFramework GetTestFramework(IUnresolvedMember member) |
||||
{ |
||||
if (member != null) { |
||||
return GetTestFramework(member.DeclaringTypeDefinition); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
ITestFramework GetTestFramework(IUnresolvedTypeDefinition c) |
||||
{ |
||||
IProject project = GetProject(c); |
||||
return GetTestFrameworkForProject(project); |
||||
} |
||||
|
||||
IProject GetProject(IUnresolvedTypeDefinition c) |
||||
{ |
||||
if (c != null && ProjectService.OpenSolution != null) { |
||||
return ProjectService.OpenSolution.FindProjectContainingFile(c.ParsedFile.FileName); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public bool IsTestClass(IUnresolvedTypeDefinition 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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
// 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 |
||||
{ |
||||
/// <summary>
|
||||
/// Determines whether #develop is currently running unit tests.
|
||||
/// </summary>
|
||||
public class RunningTestsCondition : IConditionEvaluator |
||||
{ |
||||
public bool IsValid(object caller, Condition condition) |
||||
{ |
||||
return AbstractRunTestCommand.IsRunningTest; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class SelectedTests |
||||
{ |
||||
string namespaceFilter; |
||||
TestClass c; |
||||
// TestMember member;
|
||||
List<IProject> projects = new List<IProject>(); |
||||
|
||||
public SelectedTests(IProject project, string namespaceFilter, TestClass c)//, TestMember 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 TestClass 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 IUnresolvedTypeDefinition Class {
|
||||
// get { return c; }
|
||||
// }
|
||||
//
|
||||
// public IUnresolvedMember Member {
|
||||
// get { return member; }
|
||||
// }
|
||||
} |
||||
} |
@ -0,0 +1,383 @@
@@ -0,0 +1,383 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a class that can be tested.
|
||||
/// </summary>
|
||||
public class TestClass |
||||
{ |
||||
List<IUnresolvedTypeDefinition> parts; |
||||
// TestMemberCollection testMembers;
|
||||
TestResultType testResultType; |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test class result is changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
public TestClass(IRegisteredTestFrameworks testFrameworks, params IUnresolvedTypeDefinition[] parts) |
||||
{ |
||||
this.parts = new List<IUnresolvedTypeDefinition>(parts); |
||||
this.testFrameworks = testFrameworks; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IClass for this test class.
|
||||
/// </summary>
|
||||
public IEnumerable<IUnresolvedTypeDefinition> Parts { |
||||
get { return parts; } |
||||
} |
||||
|
||||
/// <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;
|
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
/// <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(IUnresolvedTypeDefinition c) |
||||
{ |
||||
#warning not implemented!
|
||||
// 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(IUnresolvedTypeDefinition 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(IUnresolvedTypeDefinition c) |
||||
{ |
||||
return baseClassesFQNames.Contains(c.FullName); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,214 @@
@@ -0,0 +1,214 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestClassCollection : KeyedCollection<string, TestClass> |
||||
{ |
||||
TestResultType testResult = TestResultType.None; |
||||
|
||||
Dictionary<string, TestClass> passedTestClasses = new Dictionary<string, TestClass>(); |
||||
Dictionary<string, TestClass> failedTestClasses = new Dictionary<string, TestClass>(); |
||||
Dictionary<string, TestClass> ignoredTestClasses = new Dictionary<string, TestClass>(); |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test result for this collection of
|
||||
/// classes has changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
/// <summary>
|
||||
/// Raised when a class is added to this collection.
|
||||
/// </summary>
|
||||
public event TestClassEventHandler TestClassAdded; |
||||
|
||||
/// <summary>
|
||||
/// Raised when a class is removed from this collection.
|
||||
/// </summary>
|
||||
public event TestClassEventHandler TestClassRemoved; |
||||
|
||||
/// <summary>
|
||||
/// Gets the overall test results for the collection of
|
||||
/// test classes.
|
||||
/// </summary>
|
||||
public TestResultType Result { |
||||
get { |
||||
return testResult; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets all the test class test results back to none.
|
||||
/// </summary>
|
||||
public void ResetTestResults() |
||||
{ |
||||
passedTestClasses.Clear(); |
||||
failedTestClasses.Clear(); |
||||
ignoredTestClasses.Clear(); |
||||
|
||||
foreach (TestClass c in this) { |
||||
c.ResetTestResults(); |
||||
} |
||||
|
||||
SetTestResult(TestResultType.None); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test method with the specified test result.
|
||||
/// </summary>
|
||||
public void UpdateTestResult(TestResult testResult) |
||||
{ |
||||
TestClass testClass = GetTestClassFromTestMemberName(testResult.Name); |
||||
if (testClass != null) { |
||||
testClass.UpdateTestResult(testResult); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the matching test member from this set of classes.
|
||||
/// </summary>
|
||||
/// <param name="fullyQualifiedName">The fully qualified
|
||||
/// method name (e.g. Namespace.ClassName.MethodName).</param>
|
||||
/// <returns>Null if the method cannot be found.</returns>
|
||||
public TestMember GetTestMember(string fullyQualifiedName) |
||||
{ |
||||
string className = TestMember.GetQualifiedClassName(fullyQualifiedName); |
||||
if (className != null) { |
||||
if (Contains(className)) { |
||||
TestClass testClass = this[className]; |
||||
string memberName = TestMember.GetMemberName(fullyQualifiedName); |
||||
if (memberName != null) { |
||||
return testClass.GetTestMember(memberName); |
||||
} |
||||
} else { |
||||
LoggingService.Debug("TestClass not found: " + className); |
||||
} |
||||
} else { |
||||
LoggingService.Debug("Invalid test member name: " + fullyQualifiedName); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
protected override string GetKeyForItem(TestClass item) |
||||
{ |
||||
return item.QualifiedName; |
||||
} |
||||
|
||||
protected override void InsertItem(int index, TestClass item) |
||||
{ |
||||
item.ResultChanged += TestClassResultChanged; |
||||
base.InsertItem(index, item); |
||||
TestClassResultChanged(item, new EventArgs()); |
||||
OnTestClassAdded(item); |
||||
} |
||||
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
TestClass c = this[index]; |
||||
c.ResultChanged -= TestClassResultChanged; |
||||
base.RemoveItem(index); |
||||
OnTestResultNone(c.Name); |
||||
OnTestClassRemoved(c); |
||||
} |
||||
|
||||
protected void OnTestClassAdded(TestClass testClass) |
||||
{ |
||||
if (TestClassAdded != null) { |
||||
TestClassAdded(this, new TestClassEventArgs(testClass)); |
||||
} |
||||
} |
||||
|
||||
protected void OnTestClassRemoved(TestClass testClass) |
||||
{ |
||||
if (TestClassRemoved != null) { |
||||
TestClassRemoved(this, new TestClassEventArgs(testClass)); |
||||
} |
||||
} |
||||
|
||||
void TestClassResultChanged(object source, EventArgs e) |
||||
{ |
||||
TestClass c = (TestClass)source; |
||||
switch (c.Result) { |
||||
case TestResultType.None: |
||||
OnTestResultNone(c.QualifiedName); |
||||
break; |
||||
case TestResultType.Failure: |
||||
SetTestResult(TestResultType.Failure); |
||||
failedTestClasses.Add(c.QualifiedName, c); |
||||
break; |
||||
case TestResultType.Success: |
||||
passedTestClasses.Add(c.QualifiedName, c); |
||||
if (passedTestClasses.Count == Count) { |
||||
SetTestResult(TestResultType.Success); |
||||
} else if (passedTestClasses.Count + ignoredTestClasses.Count == Count) { |
||||
SetTestResult(TestResultType.Ignored); |
||||
} |
||||
break; |
||||
case TestResultType.Ignored: |
||||
ignoredTestClasses.Add(c.QualifiedName, c); |
||||
if (ignoredTestClasses.Count == Count || |
||||
ignoredTestClasses.Count + passedTestClasses.Count == Count) { |
||||
SetTestResult(TestResultType.Ignored); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
void SetTestResult(TestResultType value) |
||||
{ |
||||
TestResultType previousTestResult = testResult; |
||||
testResult = value; |
||||
if (testResult != previousTestResult) { |
||||
OnResultChanged(); |
||||
} |
||||
} |
||||
|
||||
void OnResultChanged() |
||||
{ |
||||
if (ResultChanged != null) { |
||||
ResultChanged(this, new EventArgs()); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the specified test class from the list of
|
||||
/// failed, passed and ignored tests and updates the
|
||||
/// test result state of the test class collection.
|
||||
/// </summary>
|
||||
void OnTestResultNone(string qualifiedName) |
||||
{ |
||||
passedTestClasses.Remove(qualifiedName); |
||||
failedTestClasses.Remove(qualifiedName); |
||||
ignoredTestClasses.Remove(qualifiedName); |
||||
if (ignoredTestClasses.Count + failedTestClasses.Count == 0) { |
||||
SetTestResult(TestResultType.None); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test class from the specified test result.
|
||||
/// </summary>
|
||||
TestClass GetTestClassFromTestMemberName(string memberName) |
||||
{ |
||||
if (memberName != null) { |
||||
string className = TestMember.GetQualifiedClassName(memberName); |
||||
if (className != null) { |
||||
if (Contains(className)) { |
||||
return this[className]; |
||||
} else { |
||||
LoggingService.Debug("TestClass not found: " + className); |
||||
return GetTestClassFromTestMemberName(className); |
||||
} |
||||
} else { |
||||
LoggingService.Debug("Invalid TestMember.Name: " + memberName); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents the class that will handle the TestCollection's
|
||||
/// TestClassAdded or TestClassRemoved events.
|
||||
/// </summary>
|
||||
public delegate void TestClassEventHandler(object source, TestClassEventArgs e); |
||||
|
||||
/// <summary>
|
||||
/// Provides data for the TestCollection's TestClassAdded and TestClassRemoved events.
|
||||
/// </summary>
|
||||
public class TestClassEventArgs |
||||
{ |
||||
TestClass testClass; |
||||
|
||||
public TestClassEventArgs(TestClass testClass) |
||||
{ |
||||
this.testClass = testClass; |
||||
} |
||||
|
||||
public TestClass TestClass { |
||||
get { return testClass; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
// 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.Debugging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public abstract class TestDebuggerBase : TestRunnerBase |
||||
{ |
||||
IUnitTestDebuggerService debuggerService; |
||||
IUnitTestMessageService messageService; |
||||
IDebugger debugger; |
||||
ITestResultsMonitor testResultsMonitor; |
||||
|
||||
public TestDebuggerBase() |
||||
: this(new UnitTestDebuggerService(), |
||||
new UnitTestMessageService(), |
||||
new TestResultsMonitor()) |
||||
{ |
||||
} |
||||
|
||||
public TestDebuggerBase(IUnitTestDebuggerService debuggerService, |
||||
IUnitTestMessageService messageService, |
||||
ITestResultsMonitor testResultsMonitor) |
||||
{ |
||||
this.debuggerService = debuggerService; |
||||
this.messageService = messageService; |
||||
this.testResultsMonitor = testResultsMonitor; |
||||
this.debugger = debuggerService.CurrentDebugger; |
||||
|
||||
testResultsMonitor.TestFinished += OnTestFinished; |
||||
} |
||||
|
||||
protected ITestResultsMonitor TestResultsMonitor { |
||||
get { return testResultsMonitor; } |
||||
} |
||||
|
||||
public override void Start(SelectedTests selectedTests) |
||||
{ |
||||
ProcessStartInfo startInfo = GetProcessStartInfo(selectedTests); |
||||
if (IsDebuggerRunning) { |
||||
if (CanStopDebugging()) { |
||||
debugger.Stop(); |
||||
Start(startInfo); |
||||
} |
||||
} else { |
||||
Start(startInfo); |
||||
} |
||||
} |
||||
|
||||
public bool IsDebuggerRunning { |
||||
get { return debuggerService.IsDebuggerLoaded && debugger.IsDebugging; } |
||||
} |
||||
|
||||
bool CanStopDebugging() |
||||
{ |
||||
string question = "${res:XML.MainMenu.RunMenu.Compile.StopDebuggingQuestion}"; |
||||
string caption = "${res:XML.MainMenu.RunMenu.Compile.StopDebuggingTitle}"; |
||||
return messageService.AskQuestion(question, caption); |
||||
} |
||||
|
||||
void Start(ProcessStartInfo startInfo) |
||||
{ |
||||
testResultsMonitor.Start(); |
||||
StartDebugger(startInfo); |
||||
} |
||||
|
||||
void StartDebugger(ProcessStartInfo startInfo) |
||||
{ |
||||
LogCommandLine(startInfo); |
||||
|
||||
bool running = false; |
||||
debugger.DebugStopped += DebugStopped; |
||||
try { |
||||
debugger.Start(startInfo); |
||||
running = true; |
||||
} finally { |
||||
if (!running) { |
||||
debugger.DebugStopped -= DebugStopped; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DebugStopped(object source, EventArgs e) |
||||
{ |
||||
debugger.DebugStopped -= DebugStopped; |
||||
OnAllTestsFinished(source, e); |
||||
} |
||||
|
||||
public override void Stop() |
||||
{ |
||||
if (debugger.IsDebugging) { |
||||
debugger.Stop(); |
||||
} |
||||
|
||||
testResultsMonitor.Stop(); |
||||
testResultsMonitor.Read(); |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
Stop(); |
||||
testResultsMonitor.Dispose(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
// 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 delegate void TestFinishedEventHandler(object source, TestFinishedEventArgs e); |
||||
|
||||
public class TestFinishedEventArgs : EventArgs |
||||
{ |
||||
TestResult result; |
||||
|
||||
public TestFinishedEventArgs(TestResult result) |
||||
{ |
||||
this.result = result; |
||||
} |
||||
|
||||
public TestResult Result { |
||||
get { return result; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
// 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 ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestFrameworkDescriptor |
||||
{ |
||||
Properties properties; |
||||
ITestFrameworkFactory factory; |
||||
ITestFramework testFramework; |
||||
List<string> supportedProjectFileExtensions = new List<string>(); |
||||
|
||||
public TestFrameworkDescriptor(Properties properties, ITestFrameworkFactory factory) |
||||
{ |
||||
this.properties = properties; |
||||
this.factory = factory; |
||||
|
||||
GetSupportedProjectFileExtensions(); |
||||
} |
||||
|
||||
void GetSupportedProjectFileExtensions() |
||||
{ |
||||
string extensions = properties["supportedProjects"]; |
||||
|
||||
foreach (string extension in extensions.Split(';')) { |
||||
supportedProjectFileExtensions.Add(extension.ToLowerInvariant().Trim()); |
||||
} |
||||
} |
||||
|
||||
public string Id { |
||||
get { return properties["id"]; } |
||||
} |
||||
|
||||
public ITestFramework TestFramework { |
||||
get { |
||||
CreateTestFrameworkIfNotCreated(); |
||||
return testFramework; |
||||
} |
||||
} |
||||
|
||||
void CreateTestFrameworkIfNotCreated() |
||||
{ |
||||
if (testFramework == null) { |
||||
testFramework = factory.Create(ClassName); |
||||
} |
||||
} |
||||
|
||||
string ClassName { |
||||
get { return properties["class"]; } |
||||
} |
||||
|
||||
public bool IsSupportedProject(IProject project) |
||||
{ |
||||
if (IsSupportedProjectFileExtension(project)) { |
||||
return IsSupportedByTestFramework(project); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool IsSupportedProjectFileExtension(IProject project) |
||||
{ |
||||
string extension = GetProjectFileExtension(project); |
||||
return IsSupportedProjectFileExtension(extension); |
||||
} |
||||
|
||||
string GetProjectFileExtension(IProject project) |
||||
{ |
||||
if (project != null) { |
||||
return Path.GetExtension(project.FileName).ToLowerInvariant(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
bool IsSupportedProjectFileExtension(string extension) |
||||
{ |
||||
return supportedProjectFileExtensions.Contains(extension); |
||||
} |
||||
|
||||
bool IsSupportedByTestFramework(IProject project) |
||||
{ |
||||
return TestFramework.IsTestProject(project); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// 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; |
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestFrameworkDoozer : IDoozer |
||||
{ |
||||
public TestFrameworkDoozer() |
||||
{ |
||||
} |
||||
|
||||
public bool HandleConditions { |
||||
get { return false; } |
||||
} |
||||
|
||||
public object BuildItem(BuildItemArgs args) |
||||
{ |
||||
return BuildItem(args.Codon, new TestFrameworkFactory(args.AddIn)); |
||||
} |
||||
|
||||
public TestFrameworkDescriptor BuildItem(Codon codon, ITestFrameworkFactory factory) |
||||
{ |
||||
return new TestFrameworkDescriptor(codon.Properties, factory); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
// 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 TestFrameworkFactory : ITestFrameworkFactory |
||||
{ |
||||
AddIn addin; |
||||
|
||||
public TestFrameworkFactory(AddIn addin) |
||||
{ |
||||
this.addin = addin; |
||||
} |
||||
|
||||
public ITestFramework Create(string className) |
||||
{ |
||||
return addin.CreateObject(className) as ITestFramework; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a member that can be tested.
|
||||
/// </summary>
|
||||
public class TestMember |
||||
{ |
||||
#if unused
|
||||
string prefix = String.Empty; |
||||
#endif
|
||||
IUnresolvedMember member; |
||||
TestResultType testResultType = TestResultType.None; |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test result has changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
public TestMember(IUnresolvedMember member) |
||||
{ |
||||
this.member = member; |
||||
this.DeclaringType = member.DeclaringTypeDefinition; |
||||
} |
||||
|
||||
#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, IUnresolvedMember member) |
||||
{ |
||||
this.member = member; |
||||
this.prefix = prefix; |
||||
} |
||||
#endif
|
||||
|
||||
public TestMember(IUnresolvedTypeDefinition testClass, IUnresolvedMember member) |
||||
{ |
||||
this.DeclaringType = testClass; |
||||
this.member = member; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IMember for this TestMember.
|
||||
/// </summary>
|
||||
public IUnresolvedMember 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 IUnresolvedTypeDefinition 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()); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,153 @@
@@ -0,0 +1,153 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestMemberCollection : KeyedCollection<string, TestMember> |
||||
{ |
||||
TestResultType testResult = TestResultType.None; |
||||
Dictionary<string, TestMember> passedTestMembers = new Dictionary<string, TestMember>(); |
||||
Dictionary<string, TestMember> failedTestMembers = new Dictionary<string, TestMember>(); |
||||
Dictionary<string, TestMember> ignoredTestMembers = new Dictionary<string, TestMember>(); |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test result for this collection of
|
||||
/// members has changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
/// <summary>
|
||||
/// Raised when a member is added to this collection.
|
||||
/// </summary>
|
||||
public event TestMemberEventHandler TestMemberAdded; |
||||
|
||||
/// <summary>
|
||||
/// Raised when a member is removed from this collection.
|
||||
/// </summary>
|
||||
public event TestMemberEventHandler TestMemberRemoved; |
||||
|
||||
/// <summary>
|
||||
/// Gets the overall test results for the collection of
|
||||
/// test members.
|
||||
/// </summary>
|
||||
public TestResultType Result { |
||||
get { return testResult; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets all the test members test results back to none.
|
||||
/// </summary>
|
||||
public void ResetTestResults() |
||||
{ |
||||
passedTestMembers.Clear(); |
||||
failedTestMembers.Clear(); |
||||
ignoredTestMembers.Clear(); |
||||
|
||||
foreach (TestMember member in this) { |
||||
member.Result = TestResultType.None; |
||||
} |
||||
|
||||
SetTestResult(TestResultType.None); |
||||
} |
||||
|
||||
protected override void InsertItem(int index, TestMember item) |
||||
{ |
||||
item.ResultChanged += TestMemberResultChanged; |
||||
base.InsertItem(index, item); |
||||
TestMemberResultChanged(item, new EventArgs()); |
||||
OnTestMemberAdded(item); |
||||
} |
||||
|
||||
protected override string GetKeyForItem(TestMember item) |
||||
{ |
||||
return item.Name; |
||||
} |
||||
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
TestMember member = this[index]; |
||||
member.ResultChanged -= TestMemberResultChanged; |
||||
base.RemoveItem(index); |
||||
OnTestResultNone(member.Name); |
||||
OnTestMemberRemoved(member); |
||||
} |
||||
|
||||
protected void OnTestMemberAdded(TestMember testMember) |
||||
{ |
||||
if (TestMemberAdded != null) { |
||||
TestMemberAdded(this, new TestMemberEventArgs(testMember)); |
||||
} |
||||
} |
||||
|
||||
protected void OnTestMemberRemoved(TestMember testMember) |
||||
{ |
||||
if (TestMemberRemoved != null) { |
||||
TestMemberRemoved(this, new TestMemberEventArgs(testMember)); |
||||
} |
||||
} |
||||
|
||||
void TestMemberResultChanged(object source, EventArgs e) |
||||
{ |
||||
TestMember member = (TestMember)source; |
||||
switch (member.Result) { |
||||
case TestResultType.None: |
||||
OnTestResultNone(member.Name); |
||||
break; |
||||
case TestResultType.Failure: |
||||
SetTestResult(TestResultType.Failure); |
||||
failedTestMembers.Add(member.Name, member); |
||||
break; |
||||
case TestResultType.Success: |
||||
passedTestMembers.Add(member.Name, member); |
||||
if (passedTestMembers.Count == Count) { |
||||
SetTestResult(TestResultType.Success); |
||||
} else if (passedTestMembers.Count + ignoredTestMembers.Count == Count) { |
||||
SetTestResult(TestResultType.Ignored); |
||||
} |
||||
break; |
||||
case TestResultType.Ignored: |
||||
ignoredTestMembers.Add(member.Name, member); |
||||
if (ignoredTestMembers.Count == Count || |
||||
ignoredTestMembers.Count + passedTestMembers.Count == Count) { |
||||
SetTestResult(TestResultType.Ignored); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
void SetTestResult(TestResultType value) |
||||
{ |
||||
TestResultType previousTestResult = testResult; |
||||
testResult = value; |
||||
if (testResult != previousTestResult) { |
||||
OnResultChanged(); |
||||
} |
||||
} |
||||
|
||||
void OnResultChanged() |
||||
{ |
||||
if (ResultChanged != null) { |
||||
ResultChanged(this, new EventArgs()); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the specified test member from the list of
|
||||
/// failed, passed and ignored tests and updates the
|
||||
/// test result state of the test members collection.
|
||||
/// </summary>
|
||||
void OnTestResultNone(string name) |
||||
{ |
||||
passedTestMembers.Remove(name); |
||||
failedTestMembers.Remove(name); |
||||
ignoredTestMembers.Remove(name); |
||||
if (ignoredTestMembers.Count + failedTestMembers.Count == 0) { |
||||
SetTestResult(TestResultType.None); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents the member that will handle the TestCollection's
|
||||
/// TestMemberAdded or TestMemberRemoved events.
|
||||
/// </summary>
|
||||
public delegate void TestMemberEventHandler(object source, TestMemberEventArgs e); |
||||
|
||||
/// <summary>
|
||||
/// Provides data for the TestCollection's TestMemberAdded and TestMemberRemoved events.
|
||||
/// </summary>
|
||||
public class TestMemberEventArgs |
||||
{ |
||||
TestMember testMember; |
||||
|
||||
public TestMemberEventArgs(TestMember testMember) |
||||
{ |
||||
this.testMember = testMember; |
||||
} |
||||
|
||||
public TestMember TestMember { |
||||
get { return testMember; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,298 @@
@@ -0,0 +1,298 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop.Parser; |
||||
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; |
||||
List<IUnresolvedTypeDefinition> testClasses; |
||||
List<string> rootNamespaces; |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
public TestProject(IProject project) |
||||
{ |
||||
this.project = project; |
||||
this.projectContent = project.ProjectContent; |
||||
this.testFrameworks = TestService.RegisteredTestFrameworks; |
||||
project.ProjectContent.GetAllTypeDefinitions().Where(td => td.Attributes.Select(a => a.CreateResolvedAttribute(project.ProjectContent.CreateCompilation(). |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
// return TestClass.GetTestClasses(TestClasses, ns);
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes whose namespaces start with the specified string.
|
||||
/// </summary>
|
||||
public TestClass[] GetAllTestClasses(string namespaceStartsWith) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
// 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) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
// 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(IParsedFile oldUnit, IParsedFile 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(IParsedFile oldUnit, IParsedFile 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(IUnresolvedTypeDefinition c) |
||||
{ |
||||
if (IsTestClass(c)) { |
||||
TestClass testClass = CreateTestClass(c); |
||||
// TestClasses.Add(testClass);
|
||||
} |
||||
} |
||||
|
||||
TestClass CreateTestClass(IUnresolvedTypeDefinition c) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
// return new TestClass(c, testFrameworks);
|
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test class methods based on the newly parsed class
|
||||
/// information.
|
||||
/// </summary>
|
||||
void UpdateTestClass(IUnresolvedTypeDefinition 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<IUnresolvedTypeDefinition> GetTestClassesDerivedFrom(IUnresolvedTypeDefinition c) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
// return TestClasses
|
||||
// .Where(testClass => testClass.IsDerivedFrom(c))
|
||||
// .Select(testClass => testClass.Class)
|
||||
// .ToArray();
|
||||
} |
||||
|
||||
private void UpdateClassesFromProjectContent(IEnumerable<IUnresolvedTypeDefinition> 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(IUnresolvedTypeDefinition 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>
|
||||
TestClass GetExistingTestClassInProject(IUnresolvedTypeDefinition c) |
||||
{ |
||||
// foreach (IClass existingClass in projectContent.Classes) {
|
||||
// if (IsTestClass(existingClass)) {
|
||||
// if (existingClass.DotNetName == c.DotNetName) {
|
||||
// return existingClass;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public 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; |
||||
DomRegion stackTraceFilePosition = DomRegion.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 DomRegion StackTraceFilePosition { |
||||
get { return stackTraceFilePosition; } |
||||
set { stackTraceFilePosition = value; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// 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; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public abstract class TestRunnerBase : ITestRunner |
||||
{ |
||||
public TestRunnerBase() |
||||
{ |
||||
} |
||||
|
||||
protected virtual ProcessStartInfo GetProcessStartInfo(SelectedTests selectedTests) |
||||
{ |
||||
return new ProcessStartInfo(); |
||||
} |
||||
|
||||
protected void LogCommandLine(ProcessStartInfo startInfo) |
||||
{ |
||||
string commandLine = GetCommandLine(startInfo); |
||||
OnMessageReceived(commandLine); |
||||
} |
||||
|
||||
protected string GetCommandLine(ProcessStartInfo startInfo) |
||||
{ |
||||
return String.Format("\"{0}\" {1}", startInfo.FileName, startInfo.Arguments); |
||||
} |
||||
|
||||
public event EventHandler AllTestsFinished; |
||||
|
||||
protected void OnAllTestsFinished(object source, EventArgs e) |
||||
{ |
||||
if (AllTestsFinished != null) { |
||||
AllTestsFinished(source, e); |
||||
} |
||||
} |
||||
|
||||
public event TestFinishedEventHandler TestFinished; |
||||
|
||||
protected void OnTestFinished(object source, TestFinishedEventArgs e) |
||||
{ |
||||
if (TestFinished != null) { |
||||
TestResult testResult = CreateTestResultForTestFramework(e.Result); |
||||
TestFinished(source, new TestFinishedEventArgs(testResult)); |
||||
} |
||||
} |
||||
|
||||
protected virtual TestResult CreateTestResultForTestFramework(TestResult testResult) |
||||
{ |
||||
return testResult; |
||||
} |
||||
|
||||
public event MessageReceivedEventHandler MessageReceived; |
||||
|
||||
protected virtual void OnMessageReceived(string message) |
||||
{ |
||||
if (MessageReceived != null) { |
||||
MessageReceived(this, new MessageReceivedEventArgs(message)); |
||||
} |
||||
} |
||||
|
||||
public abstract void Dispose(); |
||||
public abstract void Stop(); |
||||
public abstract void Start(SelectedTests selectedTests); |
||||
} |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// 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; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public static class TestService |
||||
{ |
||||
static IRegisteredTestFrameworks testFrameworks; |
||||
static MessageViewCategory unitTestMessageView; |
||||
|
||||
public static IRegisteredTestFrameworks RegisteredTestFrameworks { |
||||
get { |
||||
CreateRegisteredTestFrameworks(); |
||||
return testFrameworks; |
||||
} |
||||
set { testFrameworks = value; } |
||||
} |
||||
|
||||
static void CreateRegisteredTestFrameworks() |
||||
{ |
||||
if (testFrameworks == null) { |
||||
UnitTestAddInTree addInTree = new UnitTestAddInTree(); |
||||
testFrameworks = new RegisteredTestFrameworks(addInTree); |
||||
} |
||||
} |
||||
|
||||
public static MessageViewCategory UnitTestMessageView { |
||||
get { |
||||
if (unitTestMessageView == null) { |
||||
CreateUnitTestCategory(); |
||||
} |
||||
return unitTestMessageView; |
||||
} |
||||
} |
||||
|
||||
static void CreateUnitTestCategory() |
||||
{ |
||||
MessageViewCategory.Create(ref unitTestMessageView, |
||||
"UnitTesting", |
||||
"${res:ICSharpCode.NUnitPad.NUnitPadContent.PadName}"); |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
// 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.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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitTestAttributeName |
||||
{ |
||||
string name = String.Empty; |
||||
string qualifiedName = String.Empty; |
||||
string fullName = String.Empty; |
||||
StringComparer nameComparer; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the NUnit Test Attribute class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the attribute (e.g. Test) not
|
||||
/// the full name of the attribute (e.g. TestAttribute).</param>
|
||||
/// <param name="nameComparer">The string comparer to use
|
||||
/// when comparing attribute names.</param>
|
||||
public NUnitTestAttributeName(string name, StringComparer nameComparer) |
||||
{ |
||||
this.name = name; |
||||
this.nameComparer = nameComparer; |
||||
qualifiedName = String.Concat(name, "Attribute"); |
||||
fullName = String.Concat("NUnit.Framework.", name, "Attribute"); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified attribute name is a
|
||||
/// match to this attribute.
|
||||
/// </summary>
|
||||
public bool IsEqual(string attributeName) |
||||
{ |
||||
if (nameComparer.Equals(attributeName, name) || |
||||
nameComparer.Equals(attributeName, qualifiedName) || |
||||
nameComparer.Equals(attributeName, fullName)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public bool IsEqual(IAttribute attribute) |
||||
{ |
||||
return IsEqual(attribute.AttributeType.FullName); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
// 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.WinForms; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestProcessRunnerBase : TestRunnerBase |
||||
{ |
||||
IUnitTestProcessRunner processRunner; |
||||
ITestResultsMonitor testResultsMonitor; |
||||
IFileSystem fileSystem; |
||||
IUnitTestMessageService messageService; |
||||
|
||||
public TestProcessRunnerBase() |
||||
: this(new UnitTestProcessRunner(), |
||||
new TestResultsMonitor(), |
||||
new UnitTestFileService(), |
||||
new UnitTestMessageService()) |
||||
{ |
||||
} |
||||
|
||||
public TestProcessRunnerBase(TestProcessRunnerBaseContext context) |
||||
: this(context.TestProcessRunner, |
||||
context.TestResultsMonitor, |
||||
context.FileSystem, |
||||
context.MessageService) |
||||
{ |
||||
} |
||||
|
||||
public TestProcessRunnerBase(IUnitTestProcessRunner processRunner, |
||||
ITestResultsMonitor testResultsMonitor, |
||||
IFileSystem fileSystem, |
||||
IUnitTestMessageService messageService) |
||||
{ |
||||
this.processRunner = processRunner; |
||||
this.testResultsMonitor = testResultsMonitor; |
||||
this.fileSystem = fileSystem; |
||||
this.messageService = messageService; |
||||
|
||||
processRunner.LogStandardOutputAndError = false; |
||||
processRunner.OutputLineReceived += OutputLineReceived; |
||||
processRunner.ErrorLineReceived += OutputLineReceived; |
||||
processRunner.ProcessExited += OnAllTestsFinished; |
||||
testResultsMonitor.TestFinished += OnTestFinished; |
||||
} |
||||
|
||||
protected ITestResultsMonitor TestResultsMonitor { |
||||
get { return testResultsMonitor; } |
||||
} |
||||
|
||||
protected IUnitTestProcessRunner ProcessRunner { |
||||
get { return processRunner; } |
||||
} |
||||
|
||||
void OutputLineReceived(object source, LineReceivedEventArgs e) |
||||
{ |
||||
OnMessageReceived(e.Line); |
||||
} |
||||
|
||||
public override void Start(SelectedTests selectedTests) |
||||
{ |
||||
ProcessStartInfo startInfo = GetProcessStartInfo(selectedTests); |
||||
Start(startInfo); |
||||
} |
||||
|
||||
void Start(ProcessStartInfo processStartInfo) |
||||
{ |
||||
LogCommandLine(processStartInfo); |
||||
|
||||
if (ApplicationFileNameExists(processStartInfo.FileName)) { |
||||
testResultsMonitor.Start(); |
||||
processRunner.WorkingDirectory = processStartInfo.WorkingDirectory; |
||||
processRunner.Start(processStartInfo.FileName, processStartInfo.Arguments); |
||||
} else { |
||||
ShowApplicationDoesNotExistMessage(processStartInfo.FileName); |
||||
} |
||||
} |
||||
|
||||
bool ApplicationFileNameExists(string fileName) |
||||
{ |
||||
return fileSystem.FileExists(fileName); |
||||
} |
||||
|
||||
void ShowApplicationDoesNotExistMessage(string fileName) |
||||
{ |
||||
string resourceString = "${res:ICSharpCode.UnitTesting.TestRunnerNotFoundMessageFormat}"; |
||||
messageService.ShowFormattedErrorMessage(resourceString, fileName); |
||||
} |
||||
|
||||
public override void Stop() |
||||
{ |
||||
processRunner.Kill(); |
||||
testResultsMonitor.Stop(); |
||||
testResultsMonitor.Read(); |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
testResultsMonitor.Dispose(); |
||||
testResultsMonitor.TestFinished -= OnTestFinished; |
||||
processRunner.ErrorLineReceived -= OutputLineReceived; |
||||
processRunner.OutputLineReceived -= OutputLineReceived; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// 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.WinForms; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestProcessRunnerBaseContext |
||||
{ |
||||
IUnitTestProcessRunner processRunner; |
||||
ITestResultsMonitor testResultsMonitor; |
||||
IFileSystem fileSystem; |
||||
IUnitTestMessageService messageService; |
||||
|
||||
public TestProcessRunnerBaseContext() |
||||
: this(new UnitTestProcessRunner(), |
||||
new TestResultsMonitor(), |
||||
new UnitTestFileService(), |
||||
new UnitTestMessageService()) |
||||
{ |
||||
} |
||||
|
||||
public TestProcessRunnerBaseContext(IUnitTestProcessRunner processRunner, |
||||
ITestResultsMonitor testResultsMonitor, |
||||
IFileSystem fileSystem, |
||||
IUnitTestMessageService messageService) |
||||
{ |
||||
this.processRunner = processRunner; |
||||
this.testResultsMonitor = testResultsMonitor; |
||||
this.fileSystem = fileSystem; |
||||
this.messageService = messageService; |
||||
} |
||||
|
||||
public IUnitTestProcessRunner TestProcessRunner { |
||||
get { return processRunner; } |
||||
} |
||||
|
||||
public ITestResultsMonitor TestResultsMonitor { |
||||
get { return testResultsMonitor; } |
||||
} |
||||
|
||||
public IFileSystem FileSystem { |
||||
get { return fileSystem; } |
||||
} |
||||
|
||||
public IUnitTestMessageService MessageService { |
||||
get { return messageService; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
// 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.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestResultTask |
||||
{ |
||||
TestResultTask() |
||||
{ |
||||
} |
||||
|
||||
public static SDTask 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.BeginLine - 1, result.StackTraceFilePosition.BeginColumn - 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 SDTask(fileName, message, lineRef.Column, line, taskType); |
||||
} |
||||
return new SDTask(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);
|
||||
// }
|
||||
} |
||||
} |
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
// 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 System.Text; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Watches for new test results as they occur. Test results
|
||||
/// are written to a file and read in by this class.
|
||||
/// </summary>
|
||||
public class TestResultsMonitor : ITestResultsMonitor |
||||
{ |
||||
FileInfo fileInfo; |
||||
TestResultsReader testResultsReader; |
||||
FileSystemWatcher fileSystemWatcher; |
||||
|
||||
long initialFilePosition = 3; |
||||
long filePosition; |
||||
|
||||
const int BytesBufferLength = 1024; |
||||
byte[] bytes = new byte[BytesBufferLength]; |
||||
|
||||
/// <summary>
|
||||
/// Raised when a single test has been completed.
|
||||
/// </summary>
|
||||
public event TestFinishedEventHandler TestFinished; |
||||
|
||||
public TestResultsMonitor(string fileName) |
||||
{ |
||||
fileInfo = new FileInfo(fileName); |
||||
ResetFilePosition(); |
||||
} |
||||
|
||||
public TestResultsMonitor() |
||||
: this(Path.GetTempFileName()) |
||||
{ |
||||
ResetFilePosition(); |
||||
} |
||||
|
||||
public long InitialFilePosition { |
||||
get { return initialFilePosition; } |
||||
set { initialFilePosition = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the test results filename.
|
||||
/// </summary>
|
||||
public string FileName { |
||||
get { return fileInfo.FullName; } |
||||
set { fileInfo = new FileInfo(value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Starts monitoring for test results.
|
||||
/// </summary>
|
||||
public void Start() |
||||
{ |
||||
testResultsReader = new TestResultsReader(); |
||||
ResetFilePosition(); |
||||
|
||||
string filter = fileInfo.Name; |
||||
fileSystemWatcher = new FileSystemWatcher(fileInfo.DirectoryName, filter); |
||||
|
||||
if (File.Exists(fileInfo.FullName)) { |
||||
fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; |
||||
fileSystemWatcher.Changed += FileChanged; |
||||
} else { |
||||
fileSystemWatcher.Created += FileCreated; |
||||
} |
||||
fileSystemWatcher.Error += FileSystemWatcherError; |
||||
fileSystemWatcher.EnableRaisingEvents = true; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stops monitoring.
|
||||
/// </summary>
|
||||
public void Stop() |
||||
{ |
||||
if (fileSystemWatcher != null) { |
||||
fileSystemWatcher.Dispose(); |
||||
fileSystemWatcher = null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Reads the rest of the file from the current position.
|
||||
/// Raises the TestFinished event for each test result
|
||||
/// still in the file.
|
||||
/// </summary>
|
||||
public void Read() |
||||
{ |
||||
string text = ReadTextAdded(); |
||||
if (text != null) { |
||||
TestResult[] results = testResultsReader.Read(text); |
||||
OnTestResultsReceived(results); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stops monitoring and releases any resources used
|
||||
/// by the TestResultsMonitor.
|
||||
/// </summary>
|
||||
public void Dispose() |
||||
{ |
||||
Stop(); |
||||
|
||||
try { |
||||
File.Delete(FileName); |
||||
} catch { } |
||||
} |
||||
|
||||
void FileCreated(object source, FileSystemEventArgs e) |
||||
{ |
||||
fileSystemWatcher.Created -= FileCreated; |
||||
fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite; |
||||
fileSystemWatcher.Changed += FileChanged; |
||||
} |
||||
|
||||
void FileChanged(object source, FileSystemEventArgs e) |
||||
{ |
||||
Read(); |
||||
} |
||||
|
||||
void OnTestResultsReceived(TestResult[] results) |
||||
{ |
||||
if ((results.Length > 0) && (TestFinished != null)) { |
||||
foreach (TestResult result in results) { |
||||
TestFinished(this, new TestFinishedEventArgs(result)); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Reads the text added to the end of the file from the last
|
||||
/// position we read from.
|
||||
/// </summary>
|
||||
string ReadTextAdded() |
||||
{ |
||||
StringBuilder text = null; |
||||
try { |
||||
using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { |
||||
if (fs.Length > 0) { |
||||
text = new StringBuilder(); |
||||
int bytesRead = 0; |
||||
fs.Seek(filePosition, SeekOrigin.Begin); |
||||
do { |
||||
bytesRead = fs.Read(bytes, 0, BytesBufferLength); |
||||
if (bytesRead > 0) { |
||||
filePosition += bytesRead; |
||||
text.Append(UTF8Encoding.UTF8.GetString(bytes, 0, bytesRead)); |
||||
} |
||||
} while ((bytesRead > 0) && (filePosition < fs.Length)); |
||||
} |
||||
} |
||||
} catch (FileNotFoundException) { |
||||
// Test was aborted before it even started execution
|
||||
return null; |
||||
} |
||||
if (text != null) { |
||||
return text.ToString(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void FileSystemWatcherError(object source, ErrorEventArgs e) |
||||
{ |
||||
Console.WriteLine(e.GetException().ToString()); |
||||
} |
||||
|
||||
void ResetFilePosition() |
||||
{ |
||||
filePosition = initialFilePosition; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
// 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.Text; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Reads the test results file produced by the custom
|
||||
/// nunit-console application.
|
||||
/// </summary>
|
||||
public class TestResultsReader |
||||
{ |
||||
StringBuilder nameBuilder = new StringBuilder(); |
||||
StringBuilder valueBuilder = new StringBuilder(); |
||||
bool firstNameChar = true; |
||||
TestResult result; |
||||
|
||||
enum State { |
||||
WaitingForEndOfName = 0, |
||||
WaitingForStartOfValue = 1, |
||||
WaitingForEndOfValue = 2 |
||||
} |
||||
|
||||
State state = State.WaitingForEndOfName; |
||||
|
||||
public TestResultsReader() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns any TestResults that are in the text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text read in from the
|
||||
/// TestResults file.</param>
|
||||
public TestResult[] Read(string text) |
||||
{ |
||||
List<TestResult> results = new List<TestResult>(); |
||||
foreach (char ch in text) { |
||||
if (ReadNameValuePair(ch)) { |
||||
if (ReadTestResult()) { |
||||
results.Add(result); |
||||
} |
||||
} |
||||
} |
||||
return results.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Reads a name-value pair of the form:
|
||||
///
|
||||
/// Name: Value
|
||||
///
|
||||
/// A value can span multiple lines:
|
||||
///
|
||||
/// Name1: ValueLine1
|
||||
/// {SP}ValueLine2
|
||||
/// {SP}ValueLine3
|
||||
/// Name1: Value2
|
||||
///
|
||||
/// Each continued line of the value must start with
|
||||
/// a single space character to distinguish it from
|
||||
/// the start of a new name-value pair.
|
||||
/// </summary>
|
||||
/// <returns>True if a name-value pair has been
|
||||
/// successfully read in</returns>
|
||||
bool ReadNameValuePair(char ch) |
||||
{ |
||||
if (state == State.WaitingForEndOfName) { |
||||
ReadNameChar(ch); |
||||
} else if (state == State.WaitingForStartOfValue) { |
||||
// Makes sure first space is ignored.
|
||||
state = State.WaitingForEndOfValue; |
||||
} else { |
||||
return ReadValueChar(ch); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void ReadNameChar(char ch) |
||||
{ |
||||
if (ch == ':') { |
||||
state = State.WaitingForStartOfValue; |
||||
} else if (ch == '\r' || ch == '\n') { |
||||
nameBuilder = new StringBuilder(); |
||||
} else if (ch == ' ' && firstNameChar) { |
||||
state = State.WaitingForEndOfValue; |
||||
valueBuilder.Append("\r\n"); |
||||
} else if (firstNameChar) { |
||||
firstNameChar = false; |
||||
nameBuilder = new StringBuilder(); |
||||
valueBuilder = new StringBuilder(); |
||||
nameBuilder.Append(ch); |
||||
} else { |
||||
nameBuilder.Append(ch); |
||||
} |
||||
} |
||||
|
||||
bool ReadValueChar(char ch) |
||||
{ |
||||
if (ch == '\r') { |
||||
// Ignore.
|
||||
} else if (ch == '\n') { |
||||
state = State.WaitingForEndOfName; |
||||
firstNameChar = true; |
||||
return true; |
||||
} else { |
||||
valueBuilder.Append(ch); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates and updates a TestResult based on the
|
||||
/// name-value pair read in,
|
||||
/// </summary>
|
||||
/// <returns>True if a TestResult is ready to be returned
|
||||
/// to the caller.</returns>
|
||||
/// <remarks>
|
||||
/// The first name-value pair for a test result is the
|
||||
/// test name. The last name-value pair is the result of
|
||||
/// the test (Success, Failure or Ignored).</remarks>
|
||||
bool ReadTestResult() |
||||
{ |
||||
string name = nameBuilder.ToString(); |
||||
if (name == "Name") { |
||||
result = new TestResult(valueBuilder.ToString()); |
||||
} else if (result != null) { |
||||
if (name == "Message") { |
||||
result.Message = valueBuilder.ToString(); |
||||
} else if (name == "StackTrace") { |
||||
result.StackTrace = valueBuilder.ToString(); |
||||
} else if (name == "Result") { |
||||
UpdateTestSuccess(); |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void UpdateTestSuccess() |
||||
{ |
||||
string value = valueBuilder.ToString(); |
||||
if (value == "Success") { |
||||
result.ResultType = TestResultType.Success; |
||||
} else if (value == "Failure") { |
||||
result.ResultType = TestResultType.Failure; |
||||
} else { |
||||
result.ResultType = TestResultType.Ignored; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,434 @@
@@ -0,0 +1,434 @@
|
||||
// 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.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
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 : sharptr, 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); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,221 @@
@@ -0,0 +1,221 @@
|
||||
// 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.Text; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Helper to run the unit testing console application.
|
||||
/// </summary>
|
||||
public class UnitTestApplicationStartHelper |
||||
{ |
||||
/// <summary>
|
||||
/// returns full/path/to/Tools/NUnit
|
||||
/// </summary>
|
||||
public static string UnitTestApplicationDirectory { |
||||
get { |
||||
return Path.Combine(FileUtility.ApplicationRootPath, @"bin\Tools\NUnit"); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// returns full/path/to/Tools/NUnit/nunit-console.exe (or whichever nunit-console exe is right
|
||||
/// for the project - there are different .exes for .NET 4.0 and for x86-only projects.
|
||||
/// </summary>
|
||||
public string UnitTestApplication { |
||||
get { |
||||
string exe = "nunit-console"; |
||||
if (ProjectUsesDotnet20Runtime(project)) { |
||||
exe += "-dotnet2"; |
||||
} |
||||
if (IsPlatformTarget32Bit(project)) { |
||||
exe += "-x86"; |
||||
} |
||||
exe += ".exe"; |
||||
return Path.Combine(UnitTestApplicationDirectory, 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; |
||||
|
||||
public void Initialize(IProject project, IClass fixture, IMember test) |
||||
{ |
||||
Initialize(project, null, fixture, test); |
||||
} |
||||
|
||||
public void Initialize(IProject project, string namespaceFilter) |
||||
{ |
||||
Initialize(project, namespaceFilter, null, null); |
||||
} |
||||
|
||||
public void Initialize(IProject project, string namespaceFilter, IClass fixture, IMember test) |
||||
{ |
||||
this.project = project; |
||||
Assemblies.Add(project.OutputAssemblyFullPath); |
||||
if (namespaceFilter != null) { |
||||
NamespaceFilter = namespaceFilter; |
||||
} |
||||
if (fixture != null) { |
||||
Fixture = fixture.DotNetName; |
||||
if (test != null) { |
||||
Test = test.Name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public IProject Project { |
||||
get { |
||||
return project; |
||||
} |
||||
} |
||||
|
||||
/// <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.Concat("\"", UnitTestApplication, "\" ", 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.Equals(platformTarget, "x86", StringComparison.OrdinalIgnoreCase); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool ProjectUsesDotnet20Runtime(IProject project) |
||||
{ |
||||
MSBuildBasedProject msbuildProject = project as MSBuildBasedProject; |
||||
if (msbuildProject != null) { |
||||
string targetFrameworkVersion = msbuildProject.GetEvaluatedProperty("TargetFrameworkVersion"); |
||||
return !String.Equals(targetFrameworkVersion, "v4.0", StringComparison.OrdinalIgnoreCase); |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
// 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.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop; |
||||
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(DomRegion 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(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
// 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 class UnitTestProcessRunner : IUnitTestProcessRunner |
||||
{ |
||||
ProcessRunner runner; |
||||
|
||||
public event LineReceivedEventHandler OutputLineReceived { |
||||
add { runner.OutputLineReceived += value; } |
||||
remove { runner.OutputLineReceived -= value; } |
||||
} |
||||
|
||||
public event LineReceivedEventHandler ErrorLineReceived { |
||||
add { runner.ErrorLineReceived += value; } |
||||
remove { runner.ErrorLineReceived -= value; } |
||||
} |
||||
|
||||
public event EventHandler ProcessExited { |
||||
add { runner.ProcessExited += value; } |
||||
remove { runner.ProcessExited -= value; } |
||||
} |
||||
|
||||
public UnitTestProcessRunner() |
||||
{ |
||||
runner = new ProcessRunner(); |
||||
} |
||||
|
||||
public bool LogStandardOutputAndError { |
||||
get { return runner.LogStandardOutputAndError; } |
||||
set { runner.LogStandardOutputAndError = value; } |
||||
} |
||||
|
||||
public string WorkingDirectory { |
||||
get { return runner.WorkingDirectory; } |
||||
set { runner.WorkingDirectory = value; } |
||||
} |
||||
|
||||
public Dictionary<string, string> EnvironmentVariables { |
||||
get { return runner.EnvironmentVariables; } |
||||
} |
||||
|
||||
public void Start(string command, string arguments) |
||||
{ |
||||
runner.Start(command, arguments); |
||||
} |
||||
|
||||
public void Kill() |
||||
{ |
||||
runner.Kill(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
// 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.Widgets; |
||||
|
||||
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"; |
||||
|
||||
static readonly UnitTestingOptions instance = new UnitTestingOptions(); |
||||
|
||||
public static UnitTestingOptions Instance { |
||||
get { return instance; } |
||||
} |
||||
|
||||
Properties properties; |
||||
|
||||
UnitTestingOptions() |
||||
: this(PropertyService.NestedProperties(AddInOptionsName)) |
||||
{ |
||||
} |
||||
|
||||
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); } |
||||
} |
||||
|
||||
public UnitTestingOptions Clone() |
||||
{ |
||||
return new UnitTestingOptions(properties.Clone()); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue