// 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 { TestSolution testSolution; TestTreeView treeView; bool disposed; DockPanel panel; ToolBar toolBar; List> pending = new List>(); static UnitTestsPad instance; public UnitTestsPad() : this(TestService.RegisteredTestFrameworks, TestService.Solution) { } public UnitTestsPad(IRegisteredTestFrameworks testFrameworks, TestSolution testSolution) { instance = this; this.testSolution = testSolution; panel = new DockPanel(); toolBar = CreateToolBar("/SharpDevelop/Pads/UnitTestsPad/Toolbar"); panel.Children.Add(toolBar); DockPanel.SetDock(toolBar, Dock.Top); treeView = new TestTreeView(testFrameworks, testSolution); 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. SD.ParserService.LoadSolutionProjectsThread.Finished += LoadSolutionProjectsThreadFinished; OnAddedLoadSolutionProjectsThreadEndedHandler(); 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; SD.ParserService.LoadSolutionProjectsThread.Finished -= LoadSolutionProjectsThreadFinished; } } // public TestTreeView TestTreeView { // get { return treeView; } // } // public void ResetTestResults() // { // treeView.ResetTestResults(); // } // public IProject[] GetProjects() { return testSolution.TestableProjects.Select(tp => tp.Project).ToArray(); } // public TestProject GetTestProject(IProject project) // { // return treeView.GetTestProject(project); // } /// /// Updates the state of the buttons on the Unit Tests pad's /// toolbar. /// public void UpdateToolbar() { // ToolbarService.UpdateToolbar(toolBar); } /// /// Collapses all nodes. /// // public void CollapseAll() // { // if (treeView == null || treeView.Nodes == null || treeView.Nodes.Count == 0) // return; // // treeView.CollapseAll(); // } /// /// Called when a solution has been closed. /// // protected void SolutionClosed() // { // treeView.Clear(); // } // // protected void SolutionFolderRemoved(ISolutionFolder solutionFolder) // { // treeView.RemoveSolutionFolder(solutionFolder); // } /// /// If the project item removed is a reference to a unit /// test framework then the project will be removed from the /// test tree. /// // protected void ProjectItemRemoved(ProjectItem projectItem) // { // treeView.ProjectItemRemoved(projectItem); // } // // protected void ProjectItemAdded(ProjectItem projectItem) // { // treeView.ProjectItemAdded(projectItem); // } /// /// Protected method so we can test this method. /// protected void UpdateParseInfo(IUnresolvedFile oldFile, IUnresolvedFile 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().FirstOrDefault(node => node.Project == project); } /// /// Virtual method so we can override this method and return /// a dummy ToolBar when testing. /// protected virtual ToolBar CreateToolBar(string name) { return ToolBarService.CreateToolBar(treeView, treeView, name); } /// /// Virtual method so we can override this method and return /// a dummy ContextMenu when testing. /// protected virtual ContextMenu CreateContextMenu(string name) { return MenuService.CreateContextMenu(treeView, name); } // /// // /// Virtual method so we can override this method and return // /// a dummy TestTreeView when testing. // /// // protected virtual SharpTreeView CreateTestTreeView(IRegisteredTestFrameworks testFrameworks) // { // return new SharpTreeView(); // } /// /// Gets the currently open solution. /// protected virtual Solution GetOpenSolution() { return ProjectService.OpenSolution; } /// /// Determines whether the parser is currently still loading the /// solution. /// protected virtual bool IsParserLoadingSolution { get { return SD.ParserService.LoadSolutionProjectsThread.IsRunning; } } /// /// Indicates that an event handler for the ParserService's /// LoadSolutionProjectsThreadEnded event has been added /// 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) { UpdateToolbar(); } void LoadSolutionProjectsThreadFinished(object source, EventArgs e) { WorkbenchSingleton.SafeThreadAsyncCall(UpdateToolbar); Solution solution = ProjectService.OpenSolution; // WorkbenchSingleton.SafeThreadAsyncCall(SolutionLoaded, solution); } // 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); } public void ResetTestResults() { foreach (var testProject in testSolution.TestableProjects) testProject.ResetTestResults(); } } }