XPDUnitTestModule.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:17k
源码类别:

Email服务器

开发平台:

Delphi

  1. unit XPDUnitTestModule;
  2. {
  3.  $Source: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/XPDUnitTestModule.pas,v $
  4.  $Revision: 1.2 $
  5.  $Date: 2004/05/03 15:07:16 $
  6.  Last amended by $Author: pvspain $
  7.  $State: Exp $
  8.  TXPDUnitTestModuleForm:
  9.  Copyright (c) 2003 by The Excellent Programming Company Pty Ltd
  10.  (Australia) (ABN 27 005 394 918). All rights reserved.
  11.  Contact Paul Spain via email: paul@xpro.com.au
  12.  This unit is free software; you can redistribute it and/or
  13.  modify it under the terms of the GNU Lesser General Public
  14.  License as published by the Free Software Foundation; either
  15.  version 2.1 of the License, or (at your option) any later version.
  16.  This unit is distributed in the hope that it will be useful,
  17.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19.  Lesser General Public License for more details.
  20.  You should have received a copy of the GNU Lesser General Public
  21.  License along with this unit; if not, the license can be viewed at:
  22.  http://www.gnu.org/copyleft/lesser.html
  23.  or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  24.  Boston, MA  02111-1307  USA
  25.  }
  26. interface
  27. {$I JEDI.inc}
  28. uses
  29.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  30.   StdCtrls, Buttons, ExtCtrls, XPDUnitCommon, IniFiles, ComCtrls, ImgList,
  31.   XPTestedUnitParser, XPTestedUnitUtils, XPParserFilters;
  32. type
  33. ////////////////////////////////////////////////////////////////////////////
  34. //          TXPDUnitTestModuleForm declaration
  35. ////////////////////////////////////////////////////////////////////////////
  36.   TXPDUnitTestModuleForm = class(TForm)
  37.     Label1: TLabel;
  38.     UnitName: TEdit;
  39.     Label2: TLabel;
  40.     UnitFileName: TEdit;
  41.     Label3: TLabel;
  42.     UnitPath: TEdit;
  43.     SelectPath: TSpeedButton;
  44.     GroupBox1: TGroupBox;
  45.     AddToTestModule: TCheckBox;
  46.     AddToProject: TCheckBox;
  47.     CancelTestModule: TBitBtn;
  48.     CreateTestModule: TBitBtn;
  49.     Label4: TLabel;
  50.     NodeImages: TImageList;
  51.     Classes: TPanel;
  52.     TestClassesView: TTreeView;
  53.     Splitter1: TSplitter;
  54.     TestedClassesView: TTreeView;
  55.     Label5: TLabel;
  56.     StateImages: TImageList;
  57.     procedure FormCreate(Sender: TObject);
  58.     procedure FormShow(Sender: TObject);
  59.     procedure SelectPathClick(Sender: TObject);
  60.     procedure CreateTestModuleClick(Sender: TObject);
  61.     procedure FormDestroy(Sender: TObject);
  62.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  63.     procedure UnitNameChange(Sender: TObject);
  64.     procedure TestedClassesViewClick(Sender: TObject);
  65.   private
  66.     FParameters: IXPDUnitParameters;
  67.     FBehaviours: IXPDUnitBehaviours;
  68.     FPersistedValues: TIniFile;
  69.     FTestedModuleParser: IXPTestedUnitParser;
  70.     FTestedModuleFilter: IXPTestedModuleFilter;
  71.     FTestClassFilter: IXPTestClassFilter;
  72.     procedure ParseCurrentUnit;
  73.     procedure PopulateTestedClasses;
  74.     procedure UpdateTestClasses;
  75.     function GetTestClasses: IXPParserTree;
  76.     function ClickedOnStateIcon(out ANode: TTreeNode): boolean;
  77.     procedure SetNodeState(const ANode: TTreeNode; const Enabled: boolean);
  78.     function TreeToParser(const ANode: TTreeNode): IXPParserNode;
  79.     procedure UpdateNodeImage(const ANode: TTreeNode);
  80.     procedure UpdateNodeState(const ANode: TTreeNode);
  81.     procedure SetSelectedTestNode;
  82.   public
  83.     property Parameters: IXPDUnitParameters
  84.       read FParameters;
  85.     property TestClasses: IXPParserTree
  86.       read GetTestClasses;
  87.   end;
  88. ///////////////////////////////////////////////////////////////////////////////
  89. //  Unit entry point
  90. ///////////////////////////////////////////////////////////////////////////////
  91. function ShowXPDUnitTestModuleForm(out TestClasses: IXPParserTree;
  92.   out Parameters: IXPDUnitParameters): boolean;
  93. implementation
  94. uses
  95. {$IFNDEF DELPHI6_UP}
  96.   XPInterfacedObject,   // IInterface
  97.   FileCtrl,             // SelectDirectory()
  98. {$ELSE}
  99.   QDialogs,             // SelectDirectory()
  100. {$ENDIF}
  101. {$IFDEF GUI_DEMO}
  102.   TestedUnitStream,
  103. {$ENDIF}
  104.   XPDUnitSetup,         // CreateXPDUnitBehaviours()
  105.   XPDUnitParameters;    // CreateXPDUnitParameters()
  106. const CVSID: string = '$Header: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/XPDUnitTestModule.pas,v 1.2 2004/05/03 15:07:16 pvspain Exp $';
  107. {$R *.DFM}
  108. var
  109.   LForm: TXPDUnitTestModuleForm;
  110. ///////////////////////////////////////////////////////////////////////////////
  111. //  Unit entry point
  112. ///////////////////////////////////////////////////////////////////////////////
  113. function ShowXPDUnitTestModuleForm(out TestClasses: IXPParserTree;
  114.   out Parameters: IXPDUnitParameters): boolean;
  115. begin
  116.   // Singleton instance of form. Destroyed in finalization section
  117.   // Don't assign Owner as this form is part of a package, which can be removed
  118.   // from IDE at any time. We want to be in control of form destruction.
  119.   if not System.Assigned(LForm) then
  120.     LForm := TXPDUnitTestModuleForm.Create(nil);
  121.   // Extract user's settings
  122.   TestClasses := LForm.TestClasses;
  123.   Parameters := LForm.Parameters;
  124.   // Modal form
  125.   Result := (LForm.ShowModal = mrOK);
  126. end;
  127. ////////////////////////////////////////////////////////////////////////////
  128. //          TXPDUnitTestModuleForm implementation
  129. ////////////////////////////////////////////////////////////////////////////
  130. procedure TXPDUnitTestModuleForm.FormCreate(Sender: TObject);
  131. begin
  132.   FBehaviours := XPDUnitSetup.CreateXPDUnitBehaviours;
  133.   FParameters := XPDUnitParameters.CreateXPDUnitParameters;
  134.   FPersistedValues := TIniFile.Create(XPDUnitSetupFile);
  135.   FTestedModuleParser := XPTestedUnitParser.CreateXPTestedUnitParser;
  136.   FTestedModuleFilter := XPParserFilters.CreateTestedModuleFilter;
  137.   FTestClassFilter := XPParserFilters.CreateTestClassFilter;
  138. end;
  139. procedure TXPDUnitTestModuleForm.FormDestroy(Sender: TObject);
  140. begin
  141.   FPersistedValues.Free;
  142.   // Clear local reference
  143.   LForm := nil;
  144. end;
  145. procedure TXPDUnitTestModuleForm.FormClose(Sender: TObject;
  146.   var Action: TCloseAction);
  147. begin
  148.   Action := caFree;
  149.   // Persist our geometry
  150.   FPersistedValues.WriteInteger('TestModuleForm', 'Width', Width);
  151.   FPersistedValues.WriteInteger('TestModuleForm', 'Height', Height);
  152.   FPersistedValues.WriteInteger('TestModuleForm', 'TestedClassesViewWidth',
  153.     TestedClassesView.Width);
  154. end;
  155. procedure TXPDUnitTestModuleForm.FormShow(Sender: TObject);
  156. begin
  157.   // Reload our persisted data
  158.   Width := FPersistedValues.ReadInteger('TestModuleForm', 'Width', Width);
  159.   Height := FPersistedValues.ReadInteger('TestModuleForm', 'Height', Height);
  160.   TestedClassesView.Width := FPersistedValues.ReadInteger('TestModuleForm',
  161.     'TestedClassesViewWidth', TestedClassesView.Width);
  162.   AddToTestModule.Checked := FPersistedValues.ReadBool(sBehaviours,
  163.     iAddCurrentToTestModule, dAddCurrentToTestModule);
  164.   AddToProject.Checked := FPersistedValues.ReadBool(sBehaviours,
  165.     iAddCurrentToProject, dAddCurrentToProject);
  166.   // Initialise fields for *current* invocation
  167.   FParameters.ClearValues;
  168.   FParameters.EvaluateValues;
  169.   UnitName.Text := FParameters.Values[dpUnitName];
  170.   // Unit filename initialised by UnitNameChange()
  171.   UnitPath.Text := FParameters.Values[dpUnitPath];
  172.   // Setup tested class tree view
  173.   PopulateTestedClasses;
  174.   // Setup new test class tree view
  175.   UpdateTestClasses;
  176. end;
  177. procedure TXPDUnitTestModuleForm.PopulateTestedClasses;
  178. var
  179.   SectionNode: IXPParserNode;
  180.   ClassNode: IXPParserNode;
  181.   VisibilityNode: IXPParserNode;
  182.   MethodNode: IXPParserNode;
  183.   CurrentSection: TTreeNode;
  184.   CurrentClass: TTreeNode;
  185.   CurrentVisibility: TTreeNode;
  186. const
  187.   RootNode = nil;
  188.   NoRecurse = false;
  189.   procedure AssignImages(const Node: TTreeNode; const ImageIndex: integer);
  190.   begin
  191.     Node.ImageIndex := ImageIndex;
  192.     Node.SelectedIndex := ImageIndex;
  193.     UpdateNodeImage(Node);
  194.   end;
  195. begin
  196.   // Setup tested class tree view
  197.   ParseCurrentUnit;
  198.   FTestedModuleFilter.SetInput(FTestedModuleParser.ParseTree, FBehaviours);
  199.   FTestedModuleFilter.Children.Start;
  200.   TestedClassesView.Items.BeginUpdate;
  201.   try
  202.     TestedClassesView.Items.Clear;
  203.     while FTestedModuleFilter.Children.Next(SectionNode) do
  204.     begin
  205.       CurrentSection := TestedClassesView.Items.AddChildObject(RootNode,
  206.         SectionNode.Name, pointer(SectionNode));
  207.       AssignImages(CurrentSection, System.Ord(niSection));
  208.       SectionNode.Children.Start;
  209.       while SectionNode.Children.Next(ClassNode) do
  210.       begin
  211.         CurrentClass := TestedClassesView.Items.AddChildObject(CurrentSection,
  212.           ClassNode.Name, pointer(ClassNode));
  213.         AssignImages(CurrentClass, System.Ord(niClass));
  214.         ClassNode.Children.Start;
  215.         while ClassNode.Children.Next(VisibilityNode) do
  216.         begin
  217.           CurrentVisibility := TestedClassesView.Items.AddChildObject(
  218.             CurrentClass, VisibilityNode.Name, pointer(VisibilityNode));
  219.           AssignImages(CurrentVisibility, System.Ord(niVisibility));
  220.           VisibilityNode.Children.Start;
  221.           while VisibilityNode.Children.Next(MethodNode) do
  222.             AssignImages(TestedClassesView.Items.AddChildObject(
  223.               CurrentVisibility, MethodNode.Name, pointer(MethodNode)),
  224.               System.Ord(niMethod));
  225.         end;
  226.       end;
  227.     end;
  228.   finally
  229.     TestedClassesView.Items.EndUpdate;
  230.   end;
  231.   // Display tested classes with only topmost node expanded (showing class
  232.   // names) 
  233.   TestedClassesView.FullCollapse;
  234.   if TestedClassesView.Items.GetFirstNode <> nil then
  235.     TestedClassesView.Items.GetFirstNode.Expand(NoRecurse);
  236. end;
  237. procedure TXPDUnitTestModuleForm.UpdateTestClasses;
  238. var
  239.   SectionNode: IXPParserNode;
  240.   ClassNode: IXPParserNode;
  241.   VisibilityNode: IXPParserNode;
  242.   MethodNode: IXPParserNode;
  243.   CurrentSection: TTreeNode;
  244.   CurrentClass: TTreeNode;
  245.   CurrentVisibility: TTreeNode;
  246. const
  247.   RootNode = nil;
  248.   procedure AssignImages(const Node: TTreeNode; const ImageIndex: integer);
  249.   begin
  250.     Node.ImageIndex := ImageIndex;
  251.     Node.SelectedIndex := ImageIndex;
  252.   end;
  253. begin
  254.   FTestClassFilter.SetInput(FTestedModuleFilter);
  255.   FTestClassFilter.Children.Start;
  256.   TestClassesView.Items.BeginUpdate;
  257.   try
  258.     TestClassesView.Items.Clear;
  259.     while FTestClassFilter.Children.Next(SectionNode) do
  260.     begin
  261.       CurrentSection := TestClassesView.Items.AddChildObject(RootNode,
  262.         SectionNode.Name, pointer(SectionNode));
  263.       AssignImages(CurrentSection, System.Ord(niSection));
  264.       SectionNode.Children.Start;
  265.       while SectionNode.Children.Next(ClassNode) do
  266.       begin
  267.         CurrentClass := TestClassesView.Items.AddChildObject(
  268.           CurrentSection, FParameters.TestClassName(ClassNode.Name),
  269.           pointer(ClassNode));
  270.         AssignImages(CurrentClass, System.Ord(niClass));
  271.         ClassNode.Children.Start;
  272.         while ClassNode.Children.Next(VisibilityNode) do
  273.         begin
  274.           CurrentVisibility := TestClassesView.Items.AddChildObject(
  275.             CurrentClass, VisibilityNode.Name, nil);
  276.           AssignImages(CurrentVisibility, System.Ord(niVisibility));
  277.           VisibilityNode.Children.Start;
  278.           while VisibilityNode.Children.Next(MethodNode) do
  279.             AssignImages(TestClassesView.Items.AddChildObject(
  280.               CurrentVisibility, FParameters.TestMethodName(MethodNode.Name),
  281.               pointer(MethodNode)), System.Ord(niMethod));
  282.         end;
  283.       end;
  284.     end;
  285.     SetSelectedTestNode;
  286.   finally
  287.     TestClassesView.Items.EndUpdate;
  288.   end;
  289. end;
  290. procedure TXPDUnitTestModuleForm.ParseCurrentUnit;
  291. begin
  292. {$IFDEF GUI_DEMO}
  293.   FTestedModuleParser.Parse(TestedUnitStream.CreateTestedUnitStream);
  294. {$ELSE}
  295.   // Parse current IDE unit
  296.   FTestedModuleParser.Parse;
  297. {$ENDIF}
  298. end;
  299. procedure TXPDUnitTestModuleForm.SelectPathClick(Sender: TObject);
  300. const
  301.   PathDelimiter  = '';
  302. var
  303. {$IFDEF DELPHI7_UP}
  304.   Directory: WideString;
  305. {$ELSE}
  306.   Directory: string;
  307. {$ENDIF}
  308. begin
  309.   Directory := SysUtils.Trim(UnitPath.Text);
  310.   if SelectDirectory('Choose TestModule directory...', '', Directory) then
  311.     UnitPath.Text := Directory + PathDelimiter;
  312. end;
  313. procedure TXPDUnitTestModuleForm.CreateTestModuleClick(Sender: TObject);
  314. begin
  315.   // Persist our settings
  316.   FPersistedValues.WriteBool(sBehaviours, iAddCurrentToTestModule,
  317.     AddToTestModule.Checked);
  318.   FPersistedValues.WriteBool(sBehaviours, iAddCurrentToProject,
  319.     AddToProject.Checked);
  320.   // Apply user values
  321.   FParameters.Values[dpUnitName] := SysUtils.Trim(UnitName.Text);
  322.   FParameters.Values[dpUnitPath] := SysUtils.Trim(UnitPath.Text);
  323.   // Close form now
  324.   // * parameters and tested classes handed on via public properties
  325.   // * ModalResult is mrOK
  326. end;
  327. procedure TXPDUnitTestModuleForm.UnitNameChange(Sender: TObject);
  328. begin
  329.   UnitFileName.Text := SysUtils.Format('%s.pas',
  330.     [SysUtils.Trim(UnitName.Text)]);
  331. end;
  332. function TXPDUnitTestModuleForm.GetTestClasses: IXPParserTree;
  333. begin
  334.   Result := FTestClassFilter;
  335. end;
  336. procedure TXPDUnitTestModuleForm.TestedClassesViewClick(Sender: TObject);
  337. var
  338.   Node: TTreeNode;
  339. begin
  340.   if ClickedOnStateIcon(Node) then
  341.   begin
  342.     SetNodeState(Node, not TreeToParser(Node).Enabled);
  343.     UpdateTestClasses;
  344.   end
  345.   else
  346.     SetSelectedTestNode;
  347. end;
  348. procedure TXPDUnitTestModuleForm.SetSelectedTestNode;
  349. var
  350.   TestedNode, TestNode: TTreeNode;
  351.   MatchingNodeText: string;
  352. const
  353.   Recurse = true;
  354. begin
  355.   TestClassesView.Items.BeginUpdate;
  356.   try
  357.     // Expand to show class nodes only
  358.     TestClassesView.FullCollapse;
  359.     if TestClassesView.Items.GetFirstNode <> nil then
  360.       TestClassesView.Items.GetFirstNode.Expand(not Recurse);
  361.     // Now expand corresponding node to selected in TestedClassesView
  362.     TestedNode := TestedClassesView.Selected;
  363.     if Assigned(TestedNode) then
  364.     begin
  365.       // search for 'class' level node
  366.       while System.Assigned(TestedNode.Parent)
  367.         and System.Assigned(TestedNode.Parent.Parent) do
  368.         TestedNode := TestedNode.Parent;
  369.       if System.Assigned(TestedNode.Parent)
  370.         and TreeToParser(TestedNode).Enabled then
  371.       begin
  372.         MatchingNodeText := FParameters.TestClassName(TestedNode.Text);
  373.         TestNode := TestClassesView.Items.GetFirstNode.GetFirstChild;
  374.         while Assigned(TestNode) and (TestNode.Text <> MatchingNodeText) do
  375.           TestNode := TestClassesView.Items.GetFirstNode.GetNextChild(TestNode);
  376.         if Assigned(TestNode) then
  377.         begin
  378.           TestNode.Focused := true;
  379.           TestNode.Expand(Recurse);
  380.         end;
  381.       end;
  382.     end;
  383.   finally
  384.     TestClassesView.Items.EndUpdate;
  385.   end;
  386. end;
  387. function TXPDUnitTestModuleForm.ClickedOnStateIcon(
  388.   out ANode: TTreeNode): boolean;
  389. var
  390.   HitInfo: THitTests;
  391.   Pos: TPoint;
  392. begin
  393.   Windows.GetCursorPos(Pos);
  394.   Pos := TestedClassesView.ScreenToClient(Pos);
  395.   HitInfo := TestedClassesView.GetHitTestInfoAt(Pos.X, Pos.Y);
  396.   ANode := TestedClassesView.GetNodeAt(Pos.X, Pos.Y);
  397.   Result := System.Assigned(ANode) and (HtOnStateIcon in HitInfo);
  398. end;
  399. procedure TXPDUnitTestModuleForm.SetNodeState(const ANode: TTreeNode;
  400.   const Enabled :boolean);
  401. var
  402.   MostSeniorChanged: TTreeNode;
  403.   Node: TTreeNode;
  404. begin
  405.   System.Assert(System.Assigned(ANode));
  406.   Node := ANode;
  407.   TreeToParser(Node).Enabled := Enabled;
  408.   MostSeniorChanged := Node;
  409.   // update ancestors if enabling
  410.   if Enabled then
  411.   begin
  412.     while System.Assigned(Node.Parent) do
  413.     begin
  414.       Node := Node.Parent;
  415.       if not TreeToParser(Node).Enabled then
  416.       begin // changed
  417.         TreeToParser(Node).Enabled := true;
  418.         MostSeniorChanged := Node;
  419.       end;
  420.     end;
  421.   end;
  422.   TestedClassesView.Items.BeginUpdate;
  423.   try
  424.     UpdateNodeState(MostSeniorChanged);
  425.   finally
  426.     TestedClassesView.Items.EndUpdate;
  427.   end;
  428. end;
  429. function TXPDUnitTestModuleForm.TreeToParser(
  430.   const ANode: TTreeNode): IXPParserNode;
  431. begin
  432.   System.Assert(System.Assigned(ANode)
  433.     and SysUtils.Supports(IInterface(ANode.Data), IXPParserNode, Result));
  434. end;
  435. procedure TXPDUnitTestModuleForm.UpdateNodeImage(const ANode: TTreeNode);
  436. var
  437.   ParserNode: IXPParserNode;
  438.   Node: TTreeNode;
  439. begin
  440.   Node := ANode;
  441.   ParserNode := TreeToParser(Node);
  442.   if not ParserNode.Enabled then
  443.     Node.StateIndex := System.Ord(siDisabled)
  444.   else if (Node.Parent <> nil)
  445.     and (Node.Parent.StateIndex <= System.Ord(siParentDisabled)) then
  446.     Node.StateIndex := System.Ord(siParentDisabled)
  447.   else
  448.     Node.StateIndex := System.Ord(siEnabled);
  449. end;
  450. procedure TXPDUnitTestModuleForm.UpdateNodeState(const ANode: TTreeNode);
  451. var
  452.   Node: TTreeNode;
  453. begin
  454.   System.Assert(System.Assigned(ANode));
  455.   Node := ANode;
  456.   UpdateNodeImage(Node);
  457.   if Node.HasChildren then
  458.   begin
  459.     Node := Node.GetFirstChild;
  460.     while System.Assigned(Node) do
  461.     begin
  462.       UpdateNodeState(Node);
  463.       Node := Node.getNextSibling;
  464.     end;
  465.   end;
  466. end;
  467. initialization
  468. finalization
  469.   LForm.Free;
  470. end.