You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.3 KiB
175 lines
5.3 KiB
// 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 System.Collections.Specialized; |
|
using System.Linq; |
|
using ICSharpCode.Core; |
|
using ICSharpCode.NRefactory.TypeSystem; |
|
using ICSharpCode.SharpDevelop; |
|
using ICSharpCode.SharpDevelop.Parser; |
|
using ICSharpCode.SharpDevelop.Project; |
|
|
|
namespace ICSharpCode.UnitTesting |
|
{ |
|
/// <summary> |
|
/// Manages the collection of TestProjects. |
|
/// </summary> |
|
sealed class TestSolution : TestBase, ITestSolution |
|
{ |
|
readonly IResourceService resourceService; |
|
readonly ITestService testService; |
|
readonly List<ProjectChangeListener> changeListeners = new List<ProjectChangeListener>(); |
|
|
|
public TestSolution(ITestService testService, IResourceService resourceService) |
|
{ |
|
if (testService == null) |
|
throw new ArgumentNullException("testService"); |
|
if (resourceService == null) |
|
throw new ArgumentNullException("resourceService"); |
|
this.testService = testService; |
|
this.resourceService = resourceService; |
|
SD.ProjectService.AllProjects.CollectionChanged += OnProjectsCollectionChanged; |
|
SD.ParserService.LoadSolutionProjectsThread.Finished += SD_ParserService_LoadSolutionProjectsThread_Finished; |
|
foreach (var project in SD.ProjectService.AllProjects) { |
|
AddProject(project); |
|
} |
|
SD_ParserService_LoadSolutionProjectsThread_Finished(null, null); |
|
} |
|
|
|
public override string DisplayName { |
|
get { return resourceService.GetString("ICSharpCode.UnitTesting.AllTestsTreeNode.Text"); } |
|
} |
|
|
|
public override event EventHandler DisplayNameChanged { |
|
add { resourceService.LanguageChanged += value; } |
|
remove { resourceService.LanguageChanged -= value; } |
|
} |
|
|
|
public override ITestProject ParentProject { |
|
get { return null; } |
|
} |
|
|
|
public ITestProject GetTestProject(IProject project) |
|
{ |
|
for (int i = 0; i < changeListeners.Count; i++) { |
|
if (changeListeners[i].project == project) { |
|
return changeListeners[i].testProject; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
public IEnumerable<ITest> GetTestsForEntity(IEntity entity) |
|
{ |
|
if (entity == null) |
|
return Enumerable.Empty<ITest>(); |
|
ITestProject testProject = GetTestProject(entity.ParentAssembly.GetProject()); |
|
if (testProject != null) |
|
return testProject.GetTestsForEntity(entity); |
|
else |
|
return Enumerable.Empty<ITest>(); |
|
} |
|
|
|
public override IEnumerable<string> GetUnitTestNames() |
|
{ |
|
foreach (var project in changeListeners.Select(l => l.testProject)) { |
|
foreach (var name in project.GetUnitTestNames()) { |
|
yield return name; |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Creates a TestProject for an IProject. |
|
/// This class takes care of changes in the test framework and will recreate the testProject |
|
/// if the test framework changes. |
|
/// </summary> |
|
class ProjectChangeListener |
|
{ |
|
readonly TestSolution testSolution; |
|
ITestFramework oldTestFramework; |
|
internal readonly IProject project; |
|
internal ITestProject testProject; |
|
|
|
public ProjectChangeListener(TestSolution testSolution, IProject project) |
|
{ |
|
this.testSolution = testSolution; |
|
this.project = project; |
|
} |
|
|
|
public void Start() |
|
{ |
|
project.ParseInformationUpdated += project_ParseInformationUpdated; |
|
CheckTestFramework(); |
|
} |
|
|
|
public void Stop() |
|
{ |
|
project.ParseInformationUpdated -= project_ParseInformationUpdated; |
|
// Remove old testProject |
|
if (testProject != null) { |
|
testSolution.NestedTestCollection.Remove(testProject); |
|
testProject = null; |
|
} |
|
} |
|
|
|
void project_ParseInformationUpdated(object sender, ParseInformationEventArgs e) |
|
{ |
|
if (testProject != null) { |
|
testProject.NotifyParseInformationChanged(e.OldUnresolvedFile, e.NewUnresolvedFile); |
|
} |
|
} |
|
|
|
internal void CheckTestFramework() |
|
{ |
|
ITestFramework newTestFramework = testSolution.testService.GetTestFrameworkForProject(project); |
|
if (newTestFramework == oldTestFramework) |
|
return; // test framework is unchanged |
|
|
|
// Remove old testProject |
|
if (testProject != null) { |
|
testSolution.NestedTestCollection.Remove(testProject); |
|
testProject = null; |
|
} |
|
// Create new testProject |
|
if (newTestFramework != null) { |
|
testProject = newTestFramework.CreateTestProject(testSolution, project); |
|
if (testProject == null) |
|
throw new InvalidOperationException("CreateTestProject() returned null"); |
|
testSolution.NestedTestCollection.Add(testProject); |
|
} |
|
oldTestFramework = newTestFramework; |
|
} |
|
} |
|
|
|
void OnProjectsCollectionChanged(IReadOnlyCollection<IProject> removedItems, IReadOnlyCollection<IProject> addedItems) |
|
{ |
|
for (int i = 0; i < changeListeners.Count; i++) { |
|
if (removedItems.Contains(changeListeners[i].project)) { |
|
changeListeners[i].Stop(); |
|
changeListeners.RemoveAt(i--); |
|
} |
|
} |
|
foreach (var project in addedItems) { |
|
AddProject(project); |
|
} |
|
} |
|
|
|
void AddProject(IProject project) |
|
{ |
|
ProjectChangeListener listener = new ProjectChangeListener(this, project); |
|
changeListeners.Add(listener); |
|
listener.Start(); |
|
} |
|
|
|
void SD_ParserService_LoadSolutionProjectsThread_Finished(object sender, EventArgs e) |
|
{ |
|
for (int i = 0; i < changeListeners.Count; i++) { |
|
changeListeners[i].CheckTestFramework(); |
|
} |
|
} |
|
} |
|
}
|
|
|