📄 testsuitetreeview.cs
字号:
#region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
/************************************************************************************
'
' Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
' Copyright 2000-2002 Philip A. Craig
'
' This software is provided 'as-is', without any express or implied warranty. In no
' event will the authors be held liable for any damages arising from the use of this
' software.
'
' Permission is granted to anyone to use this software for any purpose, including
' commercial applications, and to alter it and redistribute it freely, subject to the
' following restrictions:
'
' 1. The origin of this software must not be misrepresented; you must not claim that
' you wrote the original software. If you use this software in a product, an
' acknowledgment (see the following) in the product documentation is required.
'
' Portions Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
' or Copyright 2000-2002 Philip A. Craig
'
' 2. Altered source versions must be plainly marked as such, and must not be
' misrepresented as being the original software.
'
' 3. This notice may not be removed or altered from any source distribution.
'
'***********************************************************************************/
#endregion
using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.ComponentModel;
using NUnit.Core;
using NUnit.Util;
namespace NUnit.UiKit
{
public delegate void SelectedTestChangedHandler( UITestNode test );
public delegate void CheckedTestChangedHandler( UITestNode[] tests );
/// <summary>
/// TestSuiteTreeView is a tree view control
/// specialized for displaying the tests
/// in an assembly. Clients should always
/// use TestNode rather than TreeNode when
/// dealing with this class to be sure of
/// calling the proper methods.
/// </summary>
public class TestSuiteTreeView : TreeView
{
#region Enumeratons and instance Variables
/// <summary>
/// Indicates how a tree should be displayed
/// </summary>
public enum DisplayStyle
{
Auto, // Select based on space available
Expand, // Expand fully
Collapse, // Collpase fully
HideTests // Expand all but the fixtures, leaving
// leaf nodes hidden
}
/// <summary>
/// Hashtable provides direct access to TestNodes
/// </summary>
private Hashtable treeMap = new Hashtable();
/// <summary>
/// The TestNode on which a right click was done
/// </summary>
private TestSuiteTreeNode contextNode;
/// <summary>
/// Whether the browser supports running tests,
/// or just loading and examining them
/// </summary>
private bool runCommandSupported = true;
/// <summary>
/// Whether or not we track progress of tests visibly in the tree
/// </summary>
private bool displayProgress = true;
/// <summary>
/// How the tree is displayed immediately after loading
/// </summary>
//private DisplayStyle initialDisplay = DisplayStyle.Auto;
/// <summary>
/// Whether to clear test results when tests change
/// </summary>
private bool clearResultsOnChange = true;
/// <summary>
/// The properties dialog if displayed
/// </summary>
private TestPropertiesDialog propertiesDialog;
/// <summary>
/// Source of events that the tree responds to and
/// target for the run command.
/// </summary>
private ITestLoader loader;
public System.Windows.Forms.ImageList treeImages;
private System.ComponentModel.IContainer components;
/// <summary>
/// True if the UI should allow a run command to be selected
/// </summary>
private bool runCommandEnabled = false;
private string[] selectedCategories;
private bool excludeSelectedCategories;
#endregion
#region Construction and Initialization
public TestSuiteTreeView()
{
InitializeComponent();
this.ContextMenu = new System.Windows.Forms.ContextMenu();
this.ContextMenu.Popup += new System.EventHandler( ContextMenu_Popup );
}
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(TestSuiteTreeView));
this.treeImages = new System.Windows.Forms.ImageList(this.components);
//
// treeImages
//
this.treeImages.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit;
this.treeImages.ImageSize = new System.Drawing.Size(16, 16);
this.treeImages.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("treeImages.ImageStream")));
this.treeImages.TransparentColor = System.Drawing.Color.White;
//
// TestSuiteTreeView
//
this.ImageIndex = 0;
this.ImageList = this.treeImages;
this.SelectedImageIndex = 0;
this.DoubleClick += new System.EventHandler(this.TestSuiteTreeView_DoubleClick);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.TestSuiteTreeView_DragEnter);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.TestSuiteTreeView_DragDrop);
}
public void Initialize( ITestLoader loader, ITestEvents events )
{
this.loader = loader;
events.TestLoaded += new TestEventHandler( OnTestLoaded );
events.TestReloaded += new TestEventHandler( OnTestChanged );
events.TestUnloaded += new TestEventHandler( OnTestUnloaded );
events.RunStarting += new TestEventHandler( OnRunStarting );
events.RunFinished += new TestEventHandler( OnRunFinished );
events.TestFinished += new TestEventHandler( OnTestResult );
events.SuiteFinished+= new TestEventHandler( OnTestResult );
}
#endregion
#region Properties and Events
/// <summary>
/// Property determining whether the run command
/// is supported from the tree context menu and
/// by double-clicking test cases.
/// </summary>
[Category( "Behavior" ), DefaultValue( true )]
[Description("Indicates whether the tree context menu should include a run command")]
public bool RunCommandSupported
{
get { return runCommandSupported; }
set { runCommandSupported = value; }
}
/// <summary>
/// Property determining whether tree should redraw nodes
/// as tests are complete in order to show progress.
/// </summary>
[Category( "Behavior" ), DefaultValue( true )]
[Description("Indicates whether results should be displayed in the tree as each test completes")]
public bool DisplayTestProgress
{
get { return displayProgress; }
set { displayProgress = value; }
}
[Category( "Behavior" ), DefaultValue( true )]
[Description("Indicates whether test results should be cleared when the tests change in background")]
public bool ClearResultsOnChange
{
get { return clearResultsOnChange; }
set { clearResultsOnChange = value; }
}
/// <summary>
/// The currently selected test.
/// </summary>
[Browsable( false )]
public UITestNode SelectedTest
{
get
{
TestSuiteTreeNode node = (TestSuiteTreeNode)SelectedNode;
return node == null ? null : node.Test;
}
}
[Browsable( false )]
public UITestNode[] CheckedTests
{
get
{
CheckedTestFinder finder = new CheckedTestFinder( this );
return finder.GetCheckedTests( CheckedTestFinder.SelectionFlags.All );
}
}
[Browsable( false )]
public UITestNode[] SelectedTests
{
get
{
CheckedTestFinder finder = new CheckedTestFinder( this );
UITestNode[] result = finder.GetCheckedTests(
CheckedTestFinder.SelectionFlags.Top | CheckedTestFinder.SelectionFlags.Explicit );
if ( result.Length == 0 )
result = new UITestNode[] { this.SelectedTest };
return result;
}
}
/// <summary>
/// The currently selected test result or null
/// </summary>
[Browsable( false )]
public TestResult SelectedTestResult
{
get
{
TestSuiteTreeNode node = (TestSuiteTreeNode)SelectedNode;
return node == null ? null : node.Result;
}
}
[Browsable(false)]
public string[] SelectedCategories
{
get { return selectedCategories; }
set
{
selectedCategories = value;
SelectedCategoriesVisitor visitor = new SelectedCategoriesVisitor( selectedCategories, excludeSelectedCategories );
this.Accept( visitor );
}
}
[Browsable(false)]
public bool ExcludeSelectedCategories
{
get { return excludeSelectedCategories; }
set
{
excludeSelectedCategories = value;
SelectedCategoriesVisitor visitor = new SelectedCategoriesVisitor( selectedCategories, excludeSelectedCategories );
this.Accept( visitor );
}
}
public event SelectedTestChangedHandler SelectedTestChanged;
public event CheckedTestChangedHandler CheckedTestChanged;
/// <summary>
/// Test node corresponding to a TestInfo interface
/// </summary>
private TestSuiteTreeNode this[ITest test]
{
get{ return treeMap[test.UniqueName] as TestSuiteTreeNode; }
}
/// <summary>
/// Test node corresponding to a TestResultInfo
/// </summary>
private TestSuiteTreeNode this[TestResult result]
{
get { return treeMap[result.Test.UniqueName] as TestSuiteTreeNode; }
}
#endregion
#region Handlers for events related to loading and running tests
private void OnTestLoaded( object sender, TestEventArgs e )
{
CheckPropertiesDialog();
Load( e.Test );
runCommandEnabled = true;
}
private void OnTestChanged( object sender, TestEventArgs e )
{
UITestNode test = e.Test;
Invoke( new LoadHandler( Reload ), new object[]{ test } );
if ( ClearResultsOnChange )
ClearResults();
}
private void OnTestUnloaded( object sender, TestEventArgs e)
{
ClosePropertiesDialog();
Clear();
contextNode = null;
runCommandEnabled = false;
}
private void OnRunStarting( object sender, TestEventArgs e )
{
CheckPropertiesDialog();
ClearResults();
runCommandEnabled = false;
}
private void OnRunFinished( object sender, TestEventArgs e )
{
if ( e.Result != null )
this[e.Result].Expand();
if ( propertiesDialog != null )
propertiesDialog.Invoke( new PropertiesDisplayHandler( propertiesDialog.DisplayProperties ) );
runCommandEnabled = true;
}
private void OnTestResult( object sender, TestEventArgs e )
{
SetTestResult(e.Result);
}
#endregion
#region Context Menu
/// <summary>
/// Handles right mouse button down by
/// remembering the proper context item
/// and implements multiple select with the left button.
/// </summary>
/// <param name="e">MouseEventArgs structure with information about the mouse position and button state</param>
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right )
{
CheckPropertiesDialog();
TreeNode theNode = GetNodeAt( e.X, e.Y );
if ( theNode != null )
contextNode = theNode as TestSuiteTreeNode;
}
// else if (e.Button == MouseButtons.Left )
// {
// if ( Control.ModifierKeys == Keys.Control )
// {
// TestSuiteTreeNode theNode = GetNodeAt( e.X, e.Y ) as TestSuiteTreeNode;
// if ( theNode != null )
// theNode.Selected = true;
// }
// else
// {
// ClearSelected();
// }
// }
base.OnMouseDown( e );
}
/// <summary>
/// Build treeview context menu dynamically on popup
/// </summary>
private void ContextMenu_Popup(object sender, System.EventArgs e)
{
this.ContextMenu.MenuItems.Clear();
if ( contextNode == null )
return;
if ( RunCommandSupported )
{
// TODO: handle in Starting event
if ( loader.IsTestRunning )
runCommandEnabled = false;
MenuItem runMenuItem = new MenuItem( "&Run", new EventHandler( runMenuItem_Click ) );
runMenuItem.DefaultItem = runMenuItem.Enabled = runCommandEnabled;
this.ContextMenu.MenuItems.Add( runMenuItem );
}
if ( contextNode.Nodes.Count > 0 )
{
if ( contextNode.IsExpanded )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -