Click here to Skip to main content
15,886,873 members
Articles / Desktop Programming / Windows Forms

Traceract

Rate me:
Please Sign up or sign in to vote.
3.69/5 (9 votes)
3 Sep 20059 min read 98.6K   1.6K   37  
A prototype debug tracer with an added dimension.
/*
(c) 2005, Marc Clifton
All Rights Reserved
 
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer. 

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution. 

Neither the name of the Marc Clifton, "Advanced Unit Test", "AUT", nor the names
of its contributors may be used to endorse or promote products derived from this
software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

using System;
using System.Collections;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;

using Clifton.Tools.Strings;
using Clifton.Tools.Xml;

using Vts.KALib;
using Vts.UTCore;


namespace Vts.UTWinForm
{
	public class Form1 : System.Windows.Forms.Form
	{
		#region Controls

		private Color clrSuccess = Color.FromArgb(0,192,0);
		private Color clrFailure = Color.FromArgb(255,0,0);
		private System.Windows.Forms.TreeView tvUnitTests;
		private System.Windows.Forms.MainMenu mainMenu1;

		private System.Windows.Forms.MenuItem mnuFile;
		private System.Windows.Forms.MenuItem mnuOpen;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem mnuExit;
		private System.Windows.Forms.OpenFileDialog ofdAssembly;
		private IContainer components;

		private System.Windows.Forms.Button btnRun;
		private System.Windows.Forms.ProgressBar pbarTestProgress;
		private System.Windows.Forms.Label lblNumTests;

		private System.Windows.Forms.Label lblPass;
		private System.Windows.Forms.Label lblIgnore;
		private System.Windows.Forms.Label lblFail;
		private System.Windows.Forms.Label lblPassCount;
		private System.Windows.Forms.Label lblIgnoreCount;
		private System.Windows.Forms.Label lblFailCount;
		private System.Windows.Forms.Label lblNotRunCount;
		private System.Windows.Forms.TabControl tcStatus;
		private System.Windows.Forms.TabPage tpPass;
		private System.Windows.Forms.TabPage tpNotRun;
		private System.Windows.Forms.TabPage tpIgnore;
		private System.Windows.Forms.TabPage tpFail;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.ColumnHeader chFixture;
		private System.Windows.Forms.ColumnHeader chTest;
		private System.Windows.Forms.ColumnHeader chResults;
		private System.Windows.Forms.TabPage tpRunner;
		private System.Windows.Forms.ColumnHeader columnHeader1;
		private System.Windows.Forms.ColumnHeader columnHeader2;
		private System.Windows.Forms.ColumnHeader columnHeader3;
		private System.Windows.Forms.ListView lvIgnoredResults;
		private System.Windows.Forms.ColumnHeader columnHeader4;
		private System.Windows.Forms.ColumnHeader columnHeader5;
		private System.Windows.Forms.ColumnHeader columnHeader6;
		private System.Windows.Forms.ListView lvFailedResults;
		private System.Windows.Forms.ColumnHeader columnHeader7;
		private System.Windows.Forms.ColumnHeader columnHeader8;
		private System.Windows.Forms.ColumnHeader columnHeader9;

		private System.Windows.Forms.ListView lvPassResults;
		private System.Windows.Forms.ListView lvNotRunResults;
		private System.Windows.Forms.RadioButton rbFwdSeq;
		private System.Windows.Forms.GroupBox gbSeq;
		private System.Windows.Forms.RadioButton rbRevSeq;
		private System.Windows.Forms.ColumnHeader columnHeader11;
		private System.Windows.Forms.ColumnHeader columnHeader10;
		private System.Windows.Forms.ColumnHeader columnHeader12;
		private System.Windows.Forms.ColumnHeader columnHeader13;
		private System.Windows.Forms.ProgressBar pbarIteration;
		private System.Windows.Forms.ColumnHeader columnHeader14;
		private System.Windows.Forms.ColumnHeader columnHeader15;
		private System.Windows.Forms.Label lblStatus;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label lblRepNumber;
		private System.Windows.Forms.CheckBox chkExportXml;
		private System.Windows.Forms.CheckBox chkLaunchIE;
		private System.Windows.Forms.CheckBox chkUseXSLT;

		#endregion

		#region Fields
      
		private ArrayList[] testResults;
		private Hashtable htExtraPaths;
		private string assemblyFilename;
		private string workingDir;
		private TestRunner testRunner;
		private ArrayList allTreeNodes;
		private Hashtable testToTreeMap;

		private Hashtable treeToTestMap;

		private System.Windows.Forms.PictureBox pictureBox1;
		private System.Windows.Forms.Button btnStop;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem3;
		private int[] testCounts=new int[5];

		private TreeViewEventHandler afterNodeCheckedHandler;

//		[NonSerialized]
//		private AppDomain testDomain;

		#endregion

		#region c'tors

		public Form1(string fn)
		{
			assemblyFilename=fn;
			Initialize();
		}

		public Form1(string fn, string dir)
		{
			assemblyFilename=fn;
			workingDir=dir;
			Initialize();
		}
		public Form1()
		{
			Initialize();
		}

		public void Initialize()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			// EBH 2004.02.13	We need to hold a reference to the handler so we can selectively
			//					attach/detatch the event as needed
			afterNodeCheckedHandler = new TreeViewEventHandler(tvUnitTests_AfterCheck);
			tvUnitTests.AfterCheck += afterNodeCheckedHandler;

			testResults=new ArrayList[4];
			htExtraPaths = new Hashtable();

			for (int i=0; i<4; i++)
				testResults[i]=new ArrayList();

			System.Reflection.Assembly assembly = this.GetType().Assembly;
			System.IO.Stream iconStream;

			allTreeNodes=new ArrayList();
			testToTreeMap=new Hashtable();
			treeToTestMap = new Hashtable();

			ImageList tvImageList=new ImageList();
			iconStream = assembly.GetManifestResourceStream("UTWinForm.Untested.ico");
			tvImageList.Images.Add(new Icon(iconStream));
			iconStream = assembly.GetManifestResourceStream("UTWinForm.NotRun.ico");
			tvImageList.Images.Add(new Icon(iconStream));
			iconStream = assembly.GetManifestResourceStream("UTWinForm.Pass.ico");
			tvImageList.Images.Add(new Icon(iconStream));
			iconStream = assembly.GetManifestResourceStream("UTWinForm.Ignore.ico");
			tvImageList.Images.Add(new Icon(iconStream));
			iconStream = assembly.GetManifestResourceStream("UTWinForm.Fail.ico");
			tvImageList.Images.Add(new Icon(iconStream));
			iconStream=null;
			assembly=null;
         
			tvUnitTests.ImageList=tvImageList;

			pbarTestProgress.Step=1;
			pbarTestProgress.Minimum=0;

			pbarIteration.Step=1;
			pbarIteration.Minimum=0;

			ReadSettings(true);

			this.Closing += new CancelEventHandler(OnFormClosing);

			AppDomain.CurrentDomain.AssemblyResolve+=new ResolveEventHandler(OnAssemblyResolve);

//			AppDomain testDomain=AppDomain.CreateDomain("VTS", AppDomain.CurrentDomain.Evidence, Environment.CurrentDirectory, Environment.CurrentDirectory, true);
//			testDomain.AssemblyResolve+=new ResolveEventHandler(OnAssemblyResolve);

			if ((assemblyFilename != "") && (File.Exists(assemblyFilename)))
			{
				LoadAssembly(null);
				LoadAssemblyConfig();
			}
			else
			{
				assemblyFilename = "";
			}
			if (workingDir != null)
			{
				Environment.CurrentDirectory=workingDir;
			}
		}

		private void LoadAssemblyConfig()
		{
			XmlDatabase config=new XmlDatabase("Config");
			string fn=AppDomain.CurrentDomain.BaseDirectory+StringHelpers.RightOfRightmostOf(assemblyFilename, '\\')+".xml";
			if (File.Exists(fn))
			{
				config.Load(fn);
				string path=StringHelpers.LeftOf(tvUnitTests.Nodes[0].Text, ',');
				tvUnitTests.CollapseAll();
				tvUnitTests.Nodes[0].Expand();			// always expand the assembly node.
				foreach(TreeNode node in tvUnitTests.Nodes[0].Nodes)
				{
					ReadConfig(config, node, path);
				}
			}
		}

		private void ReadConfig(XmlDatabase config, TreeNode node, string path)
		{
			string newPath=path+"/"+node.Text;

			string isChecked=config.QueryScalar(newPath, "Checked");
			if (isChecked != null)
			{
				node.Checked=Convert.ToBoolean(isChecked);
			}

			string isExpanded=config.QueryScalar(newPath, "Expanded");
			if (isExpanded != null)
			{
				if (Convert.ToBoolean(isExpanded))
				{
					node.Expand();
				}
			}

			foreach(TreeNode child in node.Nodes)
			{
				ReadConfig(config, child, newPath);
			}
		}

		#endregion

		#region Windows Form Designer generated code
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
			this.tvUnitTests = new System.Windows.Forms.TreeView();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.mnuFile = new System.Windows.Forms.MenuItem();
			this.mnuOpen = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.mnuExit = new System.Windows.Forms.MenuItem();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.ofdAssembly = new System.Windows.Forms.OpenFileDialog();
			this.btnRun = new System.Windows.Forms.Button();
			this.pbarTestProgress = new System.Windows.Forms.ProgressBar();
			this.lblNumTests = new System.Windows.Forms.Label();
			this.lblPass = new System.Windows.Forms.Label();
			this.lblIgnore = new System.Windows.Forms.Label();
			this.lblFail = new System.Windows.Forms.Label();
			this.lblPassCount = new System.Windows.Forms.Label();
			this.lblIgnoreCount = new System.Windows.Forms.Label();
			this.lblFailCount = new System.Windows.Forms.Label();
			this.lblNotRunCount = new System.Windows.Forms.Label();
			this.tcStatus = new System.Windows.Forms.TabControl();
			this.tpRunner = new System.Windows.Forms.TabPage();
			this.pictureBox1 = new System.Windows.Forms.PictureBox();
			this.chkLaunchIE = new System.Windows.Forms.CheckBox();
			this.chkExportXml = new System.Windows.Forms.CheckBox();
			this.lblRepNumber = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.lblStatus = new System.Windows.Forms.Label();
			this.pbarIteration = new System.Windows.Forms.ProgressBar();
			this.label1 = new System.Windows.Forms.Label();
			this.gbSeq = new System.Windows.Forms.GroupBox();
			this.rbFwdSeq = new System.Windows.Forms.RadioButton();
			this.rbRevSeq = new System.Windows.Forms.RadioButton();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.chkUseXSLT = new System.Windows.Forms.CheckBox();
			this.btnStop = new System.Windows.Forms.Button();
			this.tpNotRun = new System.Windows.Forms.TabPage();
			this.lvNotRunResults = new System.Windows.Forms.ListView();
			this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
			this.tpPass = new System.Windows.Forms.TabPage();
			this.lvPassResults = new System.Windows.Forms.ListView();
			this.chFixture = new System.Windows.Forms.ColumnHeader();
			this.chTest = new System.Windows.Forms.ColumnHeader();
			this.columnHeader11 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader12 = new System.Windows.Forms.ColumnHeader();
			this.chResults = new System.Windows.Forms.ColumnHeader();
			this.columnHeader14 = new System.Windows.Forms.ColumnHeader();
			this.tpIgnore = new System.Windows.Forms.TabPage();
			this.lvIgnoredResults = new System.Windows.Forms.ListView();
			this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader6 = new System.Windows.Forms.ColumnHeader();
			this.tpFail = new System.Windows.Forms.TabPage();
			this.lvFailedResults = new System.Windows.Forms.ListView();
			this.columnHeader7 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader8 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader9 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader10 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader13 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader15 = new System.Windows.Forms.ColumnHeader();
			this.tcStatus.SuspendLayout();
			this.tpRunner.SuspendLayout();
//			((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
			this.gbSeq.SuspendLayout();
			this.tpNotRun.SuspendLayout();
			this.tpPass.SuspendLayout();
			this.tpIgnore.SuspendLayout();
			this.tpFail.SuspendLayout();
			this.SuspendLayout();
			// 
			// tvUnitTests
			// 
			this.tvUnitTests.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.tvUnitTests.CheckBoxes = true;
			this.tvUnitTests.Location = new System.Drawing.Point(8, 8);
			this.tvUnitTests.Name = "tvUnitTests";
			this.tvUnitTests.Size = new System.Drawing.Size(424, 360);
			this.tvUnitTests.TabIndex = 0;
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuFile,
            this.menuItem1});
			// 
			// mnuFile
			// 
			this.mnuFile.Index = 0;
			this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuOpen,
            this.menuItem2,
            this.mnuExit});
			this.mnuFile.Text = "&File";
			// 
			// mnuOpen
			// 
			this.mnuOpen.Index = 0;
			this.mnuOpen.Text = "&Open...";
			this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 1;
			this.menuItem2.Text = "-";
			// 
			// mnuExit
			// 
			this.mnuExit.Index = 2;
			this.mnuExit.Text = "E&xit";
			this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 1;
			this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem3});
			this.menuItem1.Text = "&Help";
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 0;
			this.menuItem3.Text = "&About AUT";
			this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
			// 
			// ofdAssembly
			// 
			this.ofdAssembly.DefaultExt = "dll";
			this.ofdAssembly.Filter = "Assemblies|*.dll";
			// 
			// btnRun
			// 
			this.btnRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnRun.Location = new System.Drawing.Point(680, 48);
			this.btnRun.Name = "btnRun";
			this.btnRun.Size = new System.Drawing.Size(112, 32);
			this.btnRun.TabIndex = 1;
			this.btnRun.Text = "&Run";
			this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
			// 
			// pbarTestProgress
			// 
			this.pbarTestProgress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.pbarTestProgress.Location = new System.Drawing.Point(504, 144);
			this.pbarTestProgress.Name = "pbarTestProgress";
			this.pbarTestProgress.Size = new System.Drawing.Size(288, 12);
			this.pbarTestProgress.TabIndex = 2;
			// 
			// lblNumTests
			// 
			this.lblNumTests.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblNumTests.Location = new System.Drawing.Point(448, 16);
			this.lblNumTests.Name = "lblNumTests";
			this.lblNumTests.Size = new System.Drawing.Size(120, 16);
			this.lblNumTests.TabIndex = 3;
			// 
			// lblPass
			// 
			this.lblPass.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblPass.Location = new System.Drawing.Point(448, 256);
			this.lblPass.Name = "lblPass";
			this.lblPass.Size = new System.Drawing.Size(64, 16);
			this.lblPass.TabIndex = 4;
			this.lblPass.Text = "Passed:";
			this.lblPass.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblIgnore
			// 
			this.lblIgnore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblIgnore.Location = new System.Drawing.Point(448, 280);
			this.lblIgnore.Name = "lblIgnore";
			this.lblIgnore.Size = new System.Drawing.Size(64, 16);
			this.lblIgnore.TabIndex = 5;
			this.lblIgnore.Text = "Ignored:";
			this.lblIgnore.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblFail
			// 
			this.lblFail.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblFail.Location = new System.Drawing.Point(448, 304);
			this.lblFail.Name = "lblFail";
			this.lblFail.Size = new System.Drawing.Size(64, 16);
			this.lblFail.TabIndex = 6;
			this.lblFail.Text = "Failed:";
			this.lblFail.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblPassCount
			// 
			this.lblPassCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblPassCount.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.lblPassCount.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.lblPassCount.Location = new System.Drawing.Point(520, 256);
			this.lblPassCount.Name = "lblPassCount";
			this.lblPassCount.Size = new System.Drawing.Size(72, 20);
			this.lblPassCount.TabIndex = 7;
			this.lblPassCount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// lblIgnoreCount
			// 
			this.lblIgnoreCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblIgnoreCount.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.lblIgnoreCount.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.lblIgnoreCount.Location = new System.Drawing.Point(520, 280);
			this.lblIgnoreCount.Name = "lblIgnoreCount";
			this.lblIgnoreCount.Size = new System.Drawing.Size(72, 20);
			this.lblIgnoreCount.TabIndex = 8;
			this.lblIgnoreCount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// lblFailCount
			// 
			this.lblFailCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblFailCount.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.lblFailCount.Location = new System.Drawing.Point(520, 304);
			this.lblFailCount.Name = "lblFailCount";
			this.lblFailCount.Size = new System.Drawing.Size(72, 20);
			this.lblFailCount.TabIndex = 9;
			this.lblFailCount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// lblNotRunCount
			// 
			this.lblNotRunCount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblNotRunCount.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.lblNotRunCount.Location = new System.Drawing.Point(520, 232);
			this.lblNotRunCount.Name = "lblNotRunCount";
			this.lblNotRunCount.Size = new System.Drawing.Size(72, 20);
			this.lblNotRunCount.TabIndex = 12;
			this.lblNotRunCount.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// tcStatus
			// 
			this.tcStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.tcStatus.Controls.Add(this.tpRunner);
			this.tcStatus.Controls.Add(this.tpNotRun);
			this.tcStatus.Controls.Add(this.tpPass);
			this.tcStatus.Controls.Add(this.tpIgnore);
			this.tcStatus.Controls.Add(this.tpFail);
			this.tcStatus.Location = new System.Drawing.Point(8, 8);
			this.tcStatus.Name = "tcStatus";
			this.tcStatus.SelectedIndex = 0;
			this.tcStatus.Size = new System.Drawing.Size(808, 400);
			this.tcStatus.TabIndex = 10;
			// 
			// tpRunner
			// 
			this.tpRunner.Controls.Add(this.pictureBox1);
			this.tpRunner.Controls.Add(this.chkLaunchIE);
			this.tpRunner.Controls.Add(this.chkExportXml);
			this.tpRunner.Controls.Add(this.lblRepNumber);
			this.tpRunner.Controls.Add(this.label3);
			this.tpRunner.Controls.Add(this.lblStatus);
			this.tpRunner.Controls.Add(this.pbarIteration);
			this.tpRunner.Controls.Add(this.tvUnitTests);
			this.tpRunner.Controls.Add(this.lblFailCount);
			this.tpRunner.Controls.Add(this.lblNotRunCount);
			this.tpRunner.Controls.Add(this.label1);
			this.tpRunner.Controls.Add(this.lblPass);
			this.tpRunner.Controls.Add(this.lblIgnore);
			this.tpRunner.Controls.Add(this.lblFail);
			this.tpRunner.Controls.Add(this.lblPassCount);
			this.tpRunner.Controls.Add(this.lblIgnoreCount);
			this.tpRunner.Controls.Add(this.btnRun);
			this.tpRunner.Controls.Add(this.pbarTestProgress);
			this.tpRunner.Controls.Add(this.lblNumTests);
			this.tpRunner.Controls.Add(this.gbSeq);
			this.tpRunner.Controls.Add(this.groupBox1);
			this.tpRunner.Controls.Add(this.chkUseXSLT);
			this.tpRunner.Controls.Add(this.btnStop);
			this.tpRunner.Location = new System.Drawing.Point(4, 22);
			this.tpRunner.Name = "tpRunner";
			this.tpRunner.Size = new System.Drawing.Size(800, 374);
			this.tpRunner.TabIndex = 4;
			this.tpRunner.Text = "Runner";
			// 
			// pictureBox1
			// 
			this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.pictureBox1.BackColor = System.Drawing.SystemColors.Control;
			this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.pictureBox1.Location = new System.Drawing.Point(560, 48);
			this.pictureBox1.Name = "pictureBox1";
			this.pictureBox1.Size = new System.Drawing.Size(112, 80);
			this.pictureBox1.TabIndex = 24;
			this.pictureBox1.TabStop = false;
			// 
			// chkLaunchIE
			// 
			this.chkLaunchIE.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.chkLaunchIE.Location = new System.Drawing.Point(640, 296);
			this.chkLaunchIE.Name = "chkLaunchIE";
			this.chkLaunchIE.Size = new System.Drawing.Size(120, 16);
			this.chkLaunchIE.TabIndex = 23;
			this.chkLaunchIE.Text = "Launch Browser";
			// 
			// chkExportXml
			// 
			this.chkExportXml.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.chkExportXml.Location = new System.Drawing.Point(624, 248);
			this.chkExportXml.Name = "chkExportXml";
			this.chkExportXml.Size = new System.Drawing.Size(112, 16);
			this.chkExportXml.TabIndex = 22;
			this.chkExportXml.Text = "Export To XML";
			this.chkExportXml.CheckedChanged += new System.EventHandler(this.chkExportXml_CheckedChanged);
			// 
			// lblRepNumber
			// 
			this.lblRepNumber.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lblRepNumber.Location = new System.Drawing.Point(440, 166);
			this.lblRepNumber.Name = "lblRepNumber";
			this.lblRepNumber.Size = new System.Drawing.Size(56, 16);
			this.lblRepNumber.TabIndex = 21;
			this.lblRepNumber.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// label3
			// 
			this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.label3.Location = new System.Drawing.Point(440, 142);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(56, 16);
			this.label3.TabIndex = 20;
			this.label3.Text = "UnitTest:";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// lblStatus
			// 
			this.lblStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
			this.lblStatus.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.lblStatus.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.lblStatus.ForeColor = System.Drawing.SystemColors.ControlText;
			this.lblStatus.Location = new System.Drawing.Point(440, 352);
			this.lblStatus.Name = "lblStatus";
			this.lblStatus.Size = new System.Drawing.Size(352, 20);
			this.lblStatus.TabIndex = 18;
			this.lblStatus.Text = "Status";
			this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// pbarIteration
			// 
			this.pbarIteration.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.pbarIteration.Location = new System.Drawing.Point(504, 168);
			this.pbarIteration.Name = "pbarIteration";
			this.pbarIteration.Size = new System.Drawing.Size(288, 12);
			this.pbarIteration.TabIndex = 17;
			// 
			// label1
			// 
			this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.label1.Location = new System.Drawing.Point(448, 232);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(64, 16);
			this.label1.TabIndex = 11;
			this.label1.Text = "Not Run:";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// gbSeq
			// 
			this.gbSeq.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.gbSeq.Controls.Add(this.rbFwdSeq);
			this.gbSeq.Controls.Add(this.rbRevSeq);
			this.gbSeq.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.gbSeq.Location = new System.Drawing.Point(440, 40);
			this.gbSeq.Name = "gbSeq";
			this.gbSeq.Size = new System.Drawing.Size(112, 88);
			this.gbSeq.TabIndex = 14;
			this.gbSeq.TabStop = false;
			this.gbSeq.Text = "Run Processes";
			// 
			// rbFwdSeq
			// 
			this.rbFwdSeq.Location = new System.Drawing.Point(16, 24);
			this.rbFwdSeq.Name = "rbFwdSeq";
			this.rbFwdSeq.Size = new System.Drawing.Size(72, 24);
			this.rbFwdSeq.TabIndex = 13;
			this.rbFwdSeq.Text = "Forward";
			// 
			// rbRevSeq
			// 
			this.rbRevSeq.Location = new System.Drawing.Point(16, 48);
			this.rbRevSeq.Name = "rbRevSeq";
			this.rbRevSeq.Size = new System.Drawing.Size(72, 24);
			this.rbRevSeq.TabIndex = 15;
			this.rbRevSeq.Text = "Reverse";
			// 
			// groupBox1
			// 
			this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.groupBox1.Location = new System.Drawing.Point(440, 208);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(168, 128);
			this.groupBox1.TabIndex = 19;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = " Results ";
			// 
			// chkUseXSLT
			// 
			this.chkUseXSLT.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.chkUseXSLT.Location = new System.Drawing.Point(640, 272);
			this.chkUseXSLT.Name = "chkUseXSLT";
			this.chkUseXSLT.Size = new System.Drawing.Size(120, 16);
			this.chkUseXSLT.TabIndex = 23;
			this.chkUseXSLT.Text = "Use XSLT";
			// 
			// btnStop
			// 
			this.btnStop.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnStop.Enabled = false;
			this.btnStop.Location = new System.Drawing.Point(680, 96);
			this.btnStop.Name = "btnStop";
			this.btnStop.Size = new System.Drawing.Size(112, 32);
			this.btnStop.TabIndex = 1;
			this.btnStop.Text = "&Stop";
			this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
			// 
			// tpNotRun
			// 
			this.tpNotRun.Controls.Add(this.lvNotRunResults);
			this.tpNotRun.Location = new System.Drawing.Point(4, 22);
			this.tpNotRun.Name = "tpNotRun";
			this.tpNotRun.Size = new System.Drawing.Size(800, 374);
			this.tpNotRun.TabIndex = 1;
			this.tpNotRun.Text = "NotRun";
			// 
			// lvNotRunResults
			// 
			this.lvNotRunResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.lvNotRunResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader1,
            this.columnHeader2,
            this.columnHeader3});
			this.lvNotRunResults.FullRowSelect = true;
			this.lvNotRunResults.GridLines = true;
			this.lvNotRunResults.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
			this.lvNotRunResults.Location = new System.Drawing.Point(0, -1);
			this.lvNotRunResults.Name = "lvNotRunResults";
			this.lvNotRunResults.Size = new System.Drawing.Size(800, 376);
			this.lvNotRunResults.TabIndex = 1;
			this.lvNotRunResults.View = System.Windows.Forms.View.Details;
			// 
			// columnHeader1
			// 
			this.columnHeader1.Text = "Fixture";
			this.columnHeader1.Width = 96;
			// 
			// columnHeader2
			// 
			this.columnHeader2.Text = "Test";
			this.columnHeader2.Width = 125;
			// 
			// columnHeader3
			// 
			this.columnHeader3.Text = "Results";
			this.columnHeader3.Width = 389;
			// 
			// tpPass
			// 
			this.tpPass.Controls.Add(this.lvPassResults);
			this.tpPass.Location = new System.Drawing.Point(4, 22);
			this.tpPass.Name = "tpPass";
			this.tpPass.Size = new System.Drawing.Size(800, 374);
			this.tpPass.TabIndex = 0;
			this.tpPass.Text = "Pass";
			// 
			// lvPassResults
			// 
			this.lvPassResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.lvPassResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.chFixture,
            this.chTest,
            this.columnHeader11,
            this.columnHeader12,
            this.chResults,
            this.columnHeader14});
			this.lvPassResults.FullRowSelect = true;
			this.lvPassResults.GridLines = true;
			this.lvPassResults.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
			this.lvPassResults.Location = new System.Drawing.Point(0, 8);
			this.lvPassResults.Name = "lvPassResults";
			this.lvPassResults.Size = new System.Drawing.Size(800, 376);
			this.lvPassResults.TabIndex = 0;
			this.lvPassResults.View = System.Windows.Forms.View.Details;
			// 
			// chFixture
			// 
			this.chFixture.Text = "Fixture";
			this.chFixture.Width = 96;
			// 
			// chTest
			// 
			this.chTest.Text = "Test";
			this.chTest.Width = 260;
			// 
			// columnHeader11
			// 
			this.columnHeader11.Text = "Time (avg)";
			this.columnHeader11.Width = 70;
			// 
			// columnHeader12
			// 
			this.columnHeader12.Text = "Ops/Sec.";
			this.columnHeader12.Width = 70;
			// 
			// chResults
			// 
			this.chResults.Text = "Results";
			this.chResults.Width = 200;
			// 
			// columnHeader14
			// 
			this.columnHeader14.Text = "Memory";
			this.columnHeader14.Width = 70;
			// 
			// tpIgnore
			// 
			this.tpIgnore.Controls.Add(this.lvIgnoredResults);
			this.tpIgnore.Location = new System.Drawing.Point(4, 22);
			this.tpIgnore.Name = "tpIgnore";
			this.tpIgnore.Size = new System.Drawing.Size(800, 374);
			this.tpIgnore.TabIndex = 2;
			this.tpIgnore.Text = "Ignore";
			// 
			// lvIgnoredResults
			// 
			this.lvIgnoredResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.lvIgnoredResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader4,
            this.columnHeader5,
            this.columnHeader6});
			this.lvIgnoredResults.FullRowSelect = true;
			this.lvIgnoredResults.GridLines = true;
			this.lvIgnoredResults.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
			this.lvIgnoredResults.Location = new System.Drawing.Point(0, -1);
			this.lvIgnoredResults.Name = "lvIgnoredResults";
			this.lvIgnoredResults.Size = new System.Drawing.Size(800, 376);
			this.lvIgnoredResults.TabIndex = 1;
			this.lvIgnoredResults.View = System.Windows.Forms.View.Details;
			// 
			// columnHeader4
			// 
			this.columnHeader4.Text = "Fixture";
			this.columnHeader4.Width = 96;
			// 
			// columnHeader5
			// 
			this.columnHeader5.Text = "Test";
			this.columnHeader5.Width = 125;
			// 
			// columnHeader6
			// 
			this.columnHeader6.Text = "Results";
			this.columnHeader6.Width = 397;
			// 
			// tpFail
			// 
			this.tpFail.Controls.Add(this.lvFailedResults);
			this.tpFail.Location = new System.Drawing.Point(4, 22);
			this.tpFail.Name = "tpFail";
			this.tpFail.Size = new System.Drawing.Size(800, 374);
			this.tpFail.TabIndex = 3;
			this.tpFail.Text = "Fail";
			// 
			// lvFailedResults
			// 
			this.lvFailedResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.lvFailedResults.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.columnHeader7,
            this.columnHeader8,
            this.columnHeader9,
            this.columnHeader10,
            this.columnHeader13,
            this.columnHeader15});
			this.lvFailedResults.FullRowSelect = true;
			this.lvFailedResults.GridLines = true;
			this.lvFailedResults.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
			this.lvFailedResults.Location = new System.Drawing.Point(0, -1);
			this.lvFailedResults.Name = "lvFailedResults";
			this.lvFailedResults.Size = new System.Drawing.Size(800, 376);
			this.lvFailedResults.TabIndex = 1;
			this.lvFailedResults.View = System.Windows.Forms.View.Details;
			// 
			// columnHeader7
			// 
			this.columnHeader7.Text = "Fixture";
			this.columnHeader7.Width = 96;
			// 
			// columnHeader8
			// 
			this.columnHeader8.Text = "Test";
			this.columnHeader8.Width = 125;
			// 
			// columnHeader9
			// 
			this.columnHeader9.Text = "Results";
			this.columnHeader9.Width = 163;
			// 
			// columnHeader10
			// 
			this.columnHeader10.Text = "Time (avg)";
			this.columnHeader10.Width = 87;
			// 
			// columnHeader13
			// 
			this.columnHeader13.Text = "Ops/Sec.";
			this.columnHeader13.Width = 82;
			// 
			// columnHeader15
			// 
			this.columnHeader15.Text = "Memory";
			// 
			// Form1
			// 
			this.ClientSize = new System.Drawing.Size(824, 414);
			this.Controls.Add(this.tcStatus);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenu1;
			this.Name = "Form1";
			this.Text = "Advanced Unit Test";
			this.tcStatus.ResumeLayout(false);
			this.tpRunner.ResumeLayout(false);
//			((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
			this.gbSeq.ResumeLayout(false);
			this.tpNotRun.ResumeLayout(false);
			this.tpPass.ResumeLayout(false);
			this.tpIgnore.ResumeLayout(false);
			this.tpFail.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		#region Main

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args) 
		{
			if (args.Length == 1)
			{
				Application.Run(new Form1(args[0]));
			}
			else if (args.Length == 2)
			{
				Application.Run(new Form1(args[0], args[1]));
			}
			else
			{
				Application.Run(new Form1());
			}
		}







		#endregion

		#region Methods

		private void LoadAssembly(AppDomain testDomain)
		{
			string curDirectory = Path.GetDirectoryName(assemblyFilename);
			Directory.SetCurrentDirectory(curDirectory);
			string curFile = Path.GetFileName(assemblyFilename);

			testRunner = TestRunner.CreateInstance();
			testRunner.ExtraPaths = htExtraPaths;

			TestRunner.RegisterTestNotificationEvent(new TestNotificationDelegate(TestEventNotification));
			TestRunner.RegisterFixtureNotificationEvent(new FixtureNotificationDelegate(FixtureEventNotification));
			TestRunner.RegisterIterationCompletedEvent(new TestIterationDelegate(IterationCompleted));
			TestRunner.RegisterRunnerCompletedEvent(new RunnerCompletedDelegate(RunnerCompleted));

			testRunner.LoadAssembly(testDomain, curFile);

			PopulateTreeView();
			SetupFileWatcher();

			lblNumTests.Text=testRunner.NumTests.ToString()+" tests.";
			lblStatus.Text="Assembly loaded.";
		}

		private void SetupFileWatcher() 
		{
			FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(assemblyFilename), Path.GetFileName(assemblyFilename));
			watcher.Changed += new FileSystemEventHandler(watcher_Changed);
			watcher.EnableRaisingEvents = true;
		}

		private void PopulateTreeView()
		{
			// EBH 2004.02.13 -	Detach the event handler for nodes being checked
			//					to avoid a lot of uneccessary firings when the
			//					treeview is populated
			tvUnitTests.AfterCheck -= afterNodeCheckedHandler;

			tvUnitTests.Nodes.Clear();
			TreeNode tnAssembly = null;
			foreach(AssemblyItem ai in testRunner.AssemblyCollection.Values)
			{
				// create a node for the assembly
				tnAssembly = tvUnitTests.Nodes.Add(ai.FullName);
				allTreeNodes.Add(tnAssembly);

				tnAssembly.Checked = true;
				// tnAssembly.Tag = ai;
				UniqueCollection namespaces = CollectNamespaces(tnAssembly);

				foreach (DictionaryEntry item in namespaces)
				{
					// create a node for the namespace
					string nsName=item.Key.ToString();
					
					TestFixture ns=item.Value as TestFixture;
					
					TreeNode tnNamespace=tnAssembly.Nodes.Add(nsName);
					allTreeNodes.Add(tnNamespace);
					tnNamespace.ImageIndex=0;
					tnNamespace.SelectedImageIndex=0;

					tnNamespace.Checked = true;
					// tnNamespace.Tag = ns;

					UniqueCollection classes = CollectClasses(nsName);

					foreach (DictionaryEntry itemClass in classes)
					{
						// create a node for class
						string className=itemClass.Key.ToString();
						TestFixture tf=itemClass.Value as TestFixture;
						TreeNode tnClass = tnNamespace.Nodes.Add(className);
						allTreeNodes.Add(tnClass);
						tnClass.ImageIndex=0;
						tnClass.ImageIndex=0;

						tnClass.Checked = true;
						// tnClass.Tag = tf;

						SortedList sl = null;
						MethodCollection methods = CollectMethods(out sl, tf);

						if (tf.HasCodePathList)
						{
							testToTreeMap.Add(tf.CodePaths, tnClass);
						}
						if (tf.HasCodePathRange)
						{
							testToTreeMap.Add(tf.CodePathRange, tnClass);
						}

						if (tf.IsProcessTest)
						{
							foreach (DictionaryEntry sortedMethodItem in sl)
							{
								string methodName=sortedMethodItem.Value as string;
								TreeNode tnMethod=tnClass.Nodes.Add(methodName);
								tnMethod.ImageIndex=0;
								tnMethod.SelectedImageIndex=0;

								tnMethod.Checked = true;

								testToTreeMap.Add(methods[methodName], tnMethod);
								treeToTestMap.Add(tnMethod, methods[methodName]);
								allTreeNodes.Add(tnMethod);
								tnMethod.Tag=methods[methodName];			// currently not used
							}
						}
						else
						{
							foreach (DictionaryEntry method in methods)
							{
								string methodName=method.Key.ToString();
								TreeNode tnMethod=tnClass.Nodes.Add(methodName);
								tnMethod.ImageIndex=0;
								tnMethod.SelectedImageIndex=0;

								tnMethod.Checked = true;
								// tnMethod.Tag = sortedMethodItem.Value;

								TestAttribute test = (TestAttribute) method.Value;
								testToTreeMap.Add(method.Value, tnMethod);
								treeToTestMap.Add(tnMethod, method.Value);
								
								allTreeNodes.Add(tnMethod);
								tnMethod.Tag=method.Value;					// currently not used
							}
						}
					}
				}
			}
//			tvUnitTests.ExpandAll();

			tvUnitTests.AfterCheck += afterNodeCheckedHandler;
		}

		private MethodCollection CollectMethods(out SortedList sl, TestFixture tf)
		{
			MethodCollection methods = new MethodCollection();
			sl = new SortedList();
			foreach(TestAttribute ta in tf.TestList)
			{
				methods.Add(ta.TestMethod.ToString(), ta);
				if (tf.IsProcessTest)
					sl.Add(ta.TestMethod.Sequence, ta.TestMethod.ToString());
			}

			return methods;
		}

		private ClassCollection CollectClasses(string nsName)
		{
			ClassCollection classes = new ClassCollection();
			foreach (TestFixture tf in testRunner.TestFixtures)
			{
				if (tf.Namespace==nsName)
				{
					foreach (TestAttribute ta in tf.TestList)
						classes.Add(ta.TestClass.ToString(), tf);
				}
			}

			return classes;
		}

		private NamespaceCollection CollectNamespaces(TreeNode tnAssembly)
		{
			NamespaceCollection namespaces=new NamespaceCollection();
			foreach (TestFixture tf in testRunner.TestFixtures)
			{
				if (tf.AssemblyName == tnAssembly.Text)
					namespaces.Add(tf.Namespace, tf);
			}

			return namespaces;
		}

		private void ClearTestResults()
		{
			pbarTestProgress.Value=0;
			pbarTestProgress.Maximum=testRunner.NumTests;
			testCounts[0]=0;
			testCounts[1]=0;
			testCounts[2]=0;
			testCounts[3]=0;
			testCounts[4]=0;
			TestRunner.ProcessDirection=rbFwdSeq.Checked ? TestRunner.ProcDir.RunProcessForward : TestRunner.ProcDir.RunProcessReverse;

			for (int i=0; i<4; i++)
			{
				testResults[i].Clear();
			}

			lvNotRunResults.Items.Clear();
			lvPassResults.Items.Clear();
			lvIgnoredResults.Items.Clear();
			lvFailedResults.Items.Clear();

			foreach (TreeNode tn in allTreeNodes)
			{
				tn.ImageIndex=0;
				tn.SelectedImageIndex=0;
			}
		}

		private void UpdateTreeParent(TreeNode tn, int testState)
		{
			if (tn != null)
			{
				int currentState=tn.ImageIndex;
				if (testState > currentState)
				{
					tn.ImageIndex=testState;
					tn.SelectedImageIndex=testState;
					UpdateTreeParent(tn.Parent, testState);
				}
			}
		}

		private void UpdateTestCounts()
		{
			lblNotRunCount.Text=testCounts[1].ToString();
			lblPassCount.Text=testCounts[2].ToString();
			lblIgnoreCount.Text=testCounts[3].ToString();
			lblFailCount.Text=testCounts[4].ToString();

			if (testCounts[4]>0)
			{
				pictureBox1.BackColor = clrFailure;
			}         
			else
			{
				pictureBox1.BackColor = clrSuccess;
			}

		}

		public void ReadSettings(bool bSetWindowPos)
		{
			String sConfig = AppDomain.CurrentDomain.BaseDirectory+"config.xml";
			XmlRegistry reg=new XmlRegistry(sConfig);
			XmlRegistryKey regKey=reg.RootKey;
			XmlRegistryKey lastSelectionKey=regKey.GetSubKey("LastSelection", true);
			XmlRegistryKey extraPathsKey=regKey.GetSubKey("ResolvedAssemblies", true);
			XmlRegistryKey settingsKey=regKey.GetSubKey("Settings", true);
			if (assemblyFilename==null)
			{
				assemblyFilename=lastSelectionKey.GetStringValue("FileName", "");
			}
			ofdAssembly.FileName=assemblyFilename;
			chkExportXml.Checked=settingsKey.GetBooleanValue("ExportXML", true);
			chkLaunchIE.Checked=settingsKey.GetBooleanValue("LaunchIE", chkExportXml.Checked);
			chkUseXSLT.Checked=settingsKey.GetBooleanValue("UseXSLT", chkExportXml.Checked);
			rbFwdSeq.Checked=settingsKey.GetBooleanValue("RunFwd", true);
			rbRevSeq.Checked=settingsKey.GetBooleanValue("RunRev", false);

			if (bSetWindowPos)
			{
				String sLoc = settingsKey.GetStringValue("WindowPos","");
				if (sLoc.Length>1)
				{
					String[] sNums = sLoc.Split(',');
					this.Location = new Point(int.Parse(sNums[0]),int.Parse(sNums[1]));
					this.Size = new Size(int.Parse(sNums[2]),int.Parse(sNums[3]));
				}
			}

			htExtraPaths.Clear();
			int nIndex=0;

			do 
			{
				XmlRegistryKey curPath = extraPathsKey.GetSubKey("Assembly"+nIndex.ToString(),false);
				if (curPath==null)
					break;

				String sID,sLoc;
				sID=curPath.GetStringValue("ID");
				sLoc=curPath.GetStringValue("Location");
				htExtraPaths[sID]=sLoc;
				nIndex++;
			}
			while (true);
		}

		public void SaveSettings()
		{
			String sConfig = AppDomain.CurrentDomain.BaseDirectory+"config.xml";
			XmlRegistry reg=new XmlRegistry(sConfig);
			XmlRegistryKey regKey=reg.RootKey;
			XmlRegistryKey lastSelectionKey=regKey.GetSubKey("LastSelection", true);
			XmlRegistryKey extraPathsKey=regKey.GetSubKey("ResolvedAssemblies", true);
			XmlRegistryKey settingsKey=regKey.GetSubKey("Settings", true);
			lastSelectionKey.SetValue("FileName", assemblyFilename);
			settingsKey.SetValue("RunFwd", rbFwdSeq.Checked);
			settingsKey.SetValue("RunRev", rbRevSeq.Checked);
			settingsKey.SetValue("ExportXML", chkExportXml.Checked);
			settingsKey.SetValue("LaunchIE", chkLaunchIE.Checked);
			settingsKey.SetValue("UseXSLT", chkUseXSLT.Checked);
			String sLoc = String.Format("{0},{1},{2},{3}",this.Location.X,this.Location.Y,this.Size.Width,this.Size.Height);
			settingsKey.SetValue("WindowPos", sLoc);

			int nIndex=0;
			IDictionaryEnumerator pathsEnum = htExtraPaths.GetEnumerator();
			while (pathsEnum.MoveNext())
			{
				XmlRegistryKey curPath = extraPathsKey.GetSubKey("Assembly"+nIndex.ToString(),true);
				curPath.SetValue("ID",pathsEnum.Key.ToString());
				curPath.SetValue("Location",pathsEnum.Value.ToString());
				nIndex++;
			}

			if(tvUnitTests.Nodes.Count > 0)
			{
				XmlDatabase config=new XmlDatabase("Config");
				string path=StringHelpers.LeftOf(tvUnitTests.Nodes[0].Text, ',');
				config.Insert(path);
				foreach(TreeNode node in tvUnitTests.Nodes[0].Nodes)
				{
					WriteConfig(config, node, path);
				}
				config.SaveAs(AppDomain.CurrentDomain.BaseDirectory+StringHelpers.RightOfRightmostOf(assemblyFilename, '\\')+".xml");
			}
		}

		private void WriteConfig(XmlDatabase config, TreeNode node, string path)
		{
			string newPath=path+"/"+node.Text;
			config.Insert(newPath,
				new XmlDatabase.FieldValuePair[]
				{
					new XmlDatabase.FieldValuePair("Checked", node.Checked.ToString()),
					new XmlDatabase.FieldValuePair("Expanded", node.IsExpanded.ToString())
				});
			foreach(TreeNode child in node.Nodes)
			{
				WriteConfig(config, child, newPath);
			}
		}

		private void UpdateDetailResultLists()
		{
			bool bWroteData=false;
			ListView[] views=new ListView[4] {lvNotRunResults, lvPassResults, lvIgnoredResults, lvFailedResults};
			for (int i=0; i<4; i++)
			{
				foreach (object obj in testResults[i])
				{
					if (obj is TestAttribute)
					{
						TestAttribute ta=(TestAttribute)obj;
						int n=(int)(1.0/ta.dTime);
						string opsPerSec=n.ToString();
						if (ta.dTime==0.0) opsPerSec="";
						ListViewItem lvi=new ListViewItem(new string[]
							{
								ta.TestClass.ToString(),
								ta.TestMethod.ToString(),
								ta.Result,
								ta.Time,
								opsPerSec,
								ta.TestMethod.MemoryUsed.ToString(),
								});
						views[i].Items.Add(lvi);
					}
					else if (obj is TestUnitAttribute)
					{
						TestUnitAttribute tua=(TestUnitAttribute)obj;
						ListViewItem lvi=new ListViewItem(new string[]
							{
								tua.TestClass.ToString(),
								"",
								tua.Result,
								"",
								"",
								""
							});
						views[i].Items.Add(lvi);
					}
				}
			}
			
			if (chkExportXml.Checked)
			{
				// Define the XML tags for the result categories
				string[] resultTypes=new string[4] {"NotRunResults", "PassResults", "IgnoredResults", "FailedResults"};
				string resultFile;
				// Create the result XML filename from the current date and time.
				resultFile="Result "+DateTime.Now.ToString("yyyy-MM-dd HHmmss")+".xml";
		   	
				// Create the XML stuff
				XmlTextWriter xmlWriter = new XmlTextWriter(resultFile,null);
		    
				xmlWriter.WriteStartDocument();
		    
				if (chkUseXSLT.Checked)
				{
					// Make the XML use a default stylesheet....
					String xslSheet = "type='text/xsl' href='disp.xsl'";
					xmlWriter.WriteProcessingInstruction("xml-stylesheet", xslSheet);
				}
		    
				// Write the Root element
				xmlWriter.WriteStartElement("Results");
		    
				// Write the current date/time
				DateTime now=DateTime.Now;
				xmlWriter.WriteStartElement("DateOfRun");
				xmlWriter.WriteElementString("Date",now.ToString("yyyy-MM-dd"));
				xmlWriter.WriteElementString("Time",now.ToString("HH:mm:ss"));
				xmlWriter.WriteEndElement();

				// Go through the categories
				for (int i=0; i<4; i++)
				{
					// Start the tag
					xmlWriter.WriteStartElement(resultTypes[i]);
		   	
					// Go through each test
					foreach (TestAttribute ta in testResults[i])
					{
						int n=(int)(1.0/ta.dTime);
						string opsPerSec=n.ToString();
		            
						// If there is no time, there shouldn't be any ops/sec
						if (ta.dTime==0.0) opsPerSec="";
		            
						// Dump all the test data
						xmlWriter.WriteStartElement("Result");
						xmlWriter.WriteElementString("Class",ta.TestClass.ToString());
						xmlWriter.WriteElementString("Method",ta.TestMethod.ToString());
						xmlWriter.WriteElementString("MinExecutionTime",ta.MinTime);
						xmlWriter.WriteElementString("AvgExecutionTime",ta.Time);
						xmlWriter.WriteElementString("MaxExecutionTime",ta.MaxTime);
						xmlWriter.WriteElementString("OperationsPerSec",opsPerSec);
						xmlWriter.WriteElementString("Returned",ta.Result);
						xmlWriter.WriteElementString("MemoryUsed",ta.TestMethod.MemoryUsed.ToString());
						xmlWriter.WriteEndElement();

						bWroteData=true;
					}
					// Close the result type tag
					xmlWriter.WriteEndElement();
				}  
				// Close the result tag       
				xmlWriter.WriteEndElement();
		    
				// Close the root tag
				xmlWriter.WriteEndDocument();
		    
				xmlWriter.Close();
				xmlWriter=null;
		    
				if (chkLaunchIE.Checked && bWroteData)
				{
					if (!File.Exists(Directory.GetCurrentDirectory()+"\\disp.xsl"))
					{
						File.Copy(AppDomain.CurrentDomain.BaseDirectory+"disp.xsl",Directory.GetCurrentDirectory()+"\\disp.xsl");
					}
					Process.Start("IExplore.exe",Directory.GetCurrentDirectory()+"\\"+resultFile);
				}
			}
		}

		private bool HasAnyCheckedChildNode(TreeNode tn) 
		{
			foreach(TreeNode node in tn.Nodes) 
				if(node.Checked)
					return true;

			return false;
		}

		private void MarkAllChildNodes(TreeNode tn, bool value) 
		{
			foreach(TreeNode node in tn.Nodes) 
			{
				if(node.Checked != value)
				{
					node.Checked = value;
					node.ImageIndex=0;
				}
			}
		}

		#endregion

		#region Event Handler

		public void OnFormClosing(Object o, CancelEventArgs e)
		{
			SaveSettings();
		}

		private void mnuOpen_Click(object sender, System.EventArgs e)
		{
			ReadSettings(false);

			this.pictureBox1.BackColor = System.Drawing.SystemColors.Control;

			if (ofdAssembly.ShowDialog()==DialogResult.OK)
			{
				assemblyFilename=ofdAssembly.FileName;
				// SaveSettings();
				LoadAssembly(null);
			}
		}

		private void mnuExit_Click(object sender, System.EventArgs e)
		{
			this.Close();
//			Application.Exit();
		}

		private void FixtureEventNotification(TestUnitAttribute tua, TestEvent testEvent)
		{
			if (testEvent==TestEvent.FixtureDone)
			{
				if (tua.Result != null)
				{
					TreeNode tn=testToTreeMap[tua] as TreeNode;
					if (tn != null)
					{
						// Create a unique instance so that multiple events don't end up cloberring the reason message.
						TestUnitAttribute t=new TestUnitAttribute();
						t.TestClass=tua.TestClass;
						t.Result=tua.Result;
						tn.ImageIndex=4;
						tn.SelectedImageIndex=4;
						UpdateTreeParent(tn.Parent, 4);
						t.ClassName=tn.Text;
						testResults[3].Add(t);
					}
				}
			}
		}

		public delegate void TestEventNotificationDlgt(TestAttribute ta, TestEvent testEvent);

		private void TestEventNotification(TestAttribute ta, TestEvent testEvent)
		{
			this.Invoke(new TestEventNotificationDlgt(TestEventNotification2), new object[] { ta, testEvent });
		}

		private void TestEventNotification2(TestAttribute ta, TestEvent testEvent)
		{
			switch (testEvent)
			{
				case TestEvent.TestDone :
				{
					TreeNode tn=testToTreeMap[ta] as TreeNode;
					if (tn != null)
					{
						int testState=Convert.ToInt32(ta.State);
						tn.ImageIndex=testState;
						tn.SelectedImageIndex=testState;
						++testCounts[testState];
						UpdateTreeParent(tn.Parent, testState);
						UpdateTestCounts();
						++pbarTestProgress.Value;
						testResults[testState-1].Add(ta);
					}
					pbarIteration.Value=0;
					lblRepNumber.Text="";
					lblStatus.Text=ta.TestMethod.ToString()+" done";
				}
					break;
			   
				case TestEvent.TestSetup :
				{
					lblStatus.Text= "Fixture setup";
				}
					break;
         
				case TestEvent.TestTearDown:
				{
					lblStatus.Text= "Fixture tear down";
				}
					break;
         
				case TestEvent.TestStart :
				{
					lblStatus.Text= ta.TestMethod.ToString()+" running";
				}
					break;
			}
		}

		private void IterationCompleted(TestAttribute ta)
		{
			pbarIteration.Maximum=ta.TestMethod.RepeatCount;
			++pbarIteration.Value;
			string s=(ta.TestMethod.CurrentRep+1).ToString()+" / "+ta.TestMethod.RepeatCount.ToString();
			lblRepNumber.Text=s;
		}

		private void AssemblyResolved(String sAssembly,String sLocation)
		{
			if (!htExtraPaths.ContainsKey(sAssembly))
			{
				Trace.WriteLine("Adding ["+sAssembly+"]");
				htExtraPaths[sAssembly]=sLocation;
			}
		}

		public delegate void RunnerCompletedDlgt(bool succeeded);

		private void RunnerCompleted(bool bSucceeded)
		{
			this.Invoke(new RunnerCompletedDlgt(RunnerCompleted2), new object[] { bSucceeded });
		}

		public void RunnerCompleted2(bool bSucceeded)
		{
			if (bSucceeded)
			{
				lblStatus.Text="Tests completed successfully.";
			}
			else
			{
				pictureBox1.BackColor = clrFailure;
				lblStatus.Text="Tests failed to complete.";
			}
			pbarTestProgress.Value=0;
			UpdateDetailResultLists();
			TestRunner.bStopASAP=false;
			btnRun.Enabled=true;
			btnStop.Enabled=false;
		}

		private void btnRun_Click(object sender, System.EventArgs e)
		{
			// SaveSettings();
			if (workingDir != null)
			{
				Environment.CurrentDirectory=workingDir;
			}

			lblStatus.Text="Initializing...";

			ClearTestResults();

			TestRunner.bStopASAP=false;
			btnRun.Enabled=false;
			btnStop.Enabled=true;

			testRunner.RunTests();
		}

		private void chkExportXml_CheckedChanged(object sender, System.EventArgs e)
		{
			chkLaunchIE.Enabled=chkExportXml.Checked;
			chkUseXSLT.Enabled=chkExportXml.Checked;
		}

		private void btnStop_Click(object sender, System.EventArgs e)
		{
			TestRunner.bStopASAP=true;
			btnStop.Enabled=false;
		}

		private void menuItem3_Click(object sender, System.EventArgs e)
		{
			AboutDlg dlg=new AboutDlg();
			dlg.ShowDialog();
		}

		private void tvUnitTests_AfterCheck(object sender, TreeViewEventArgs e)
		{
	
			if(treeToTestMap[e.Node]!=null) 
			{
				TestAttribute ta = (TestAttribute)treeToTestMap[e.Node];
				bool checkState=!e.Node.Checked;
				ta.SkipTest = checkState;
				e.Node.ImageIndex=0;

				foreach(object obj in ta.TestMethod.Attributes)
				{
					if (obj.GetType().Name=="SequenceAttribute")
					{
						bool toggleRemainder=false;
						foreach(TreeNode child in e.Node.Parent.Nodes)
						{
							if (toggleRemainder)
							{
								child.Checked=!checkState;
								child.ImageIndex=0;
								((TestAttribute)treeToTestMap[child]).SkipTest=checkState;
							}
							if (child==e.Node)
							{
								toggleRemainder=true;
							}
						}
						break;
					}
				}

				if(e.Node.Checked && !e.Node.Parent.Checked)
				{
					e.Node.Parent.Checked = true;
					e.Node.ImageIndex=0;
				}
				else if(!e.Node.Checked && !HasAnyCheckedChildNode(e.Node.Parent))
				{
					e.Node.Parent.Checked = false;
					e.Node.ImageIndex=0;
				}
			}
			else
			{
				if(e.Node.Nodes.Count > 0) 
				{
					if(e.Node.Checked)
					{
						if(!HasAnyCheckedChildNode(e.Node))
							MarkAllChildNodes(e.Node, true);
					}
					else 
					{
						MarkAllChildNodes(e.Node, false);
					}
				}
			}
		}

		private void watcher_Changed(object sender, FileSystemEventArgs e)
		{
			Trace.WriteLine(e.FullPath + " has changed: Event was " + e.ChangeType.ToString());
//			Invoke(new MethodInvoker(LoadAssembly));
		}

		#endregion

		public Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
		{
			string assemblyName=StringHelpers.LeftOf(args.Name, ',');
			Assembly assembly=null;
			assembly=LocateAssemblyIn(Environment.CurrentDirectory, assemblyName);
			return assembly;
		}

		private Assembly LocateAssemblyIn(string path, string assemblyName)
		{
			Assembly assembly=null;
			if (File.Exists(path+"\\"+assemblyName)) 
			{
				assembly=Assembly.LoadFrom(path+"\\"+assemblyName);
			} 
			else if (File.Exists(path+"\\"+assemblyName+".exe")) 
			{
				assembly=Assembly.LoadFrom(path+"\\"+assemblyName+".exe");
			} 
			else if (File.Exists(path+"\\"+assemblyName+".dll")) 
			{
				assembly=Assembly.LoadFrom(path+"\\"+assemblyName+".dll");
			} 
			return assembly;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions