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

Email服务器

开发平台:

Delphi

  1. unit XPTextTemplates;
  2. {
  3.  $Source: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/XPTextTemplates.pas,v $
  4.  $Revision: 1.2 $
  5.  $Date: 2004/05/03 15:07:16 $
  6.  Last amended by $Author: pvspain $
  7.  $State: Exp $
  8.  XPTextTemplates:
  9.  Copyright (c) 2002,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. uses
  28.   XPDUnitCommon,
  29.   XPTestedUnitUtils;
  30. type
  31.   IXPDUnitTextTemplates = interface
  32.     ['{D3AB08D7-2C2C-4E7B-B33A-F725559D3637}']
  33.     function GetTestModuleText: string;
  34.     procedure ReplaceTestClassDeclBlockReference(var Text: string);
  35.   end;
  36. function CreateXPDUnitTextTemplates(const ATestClasses: IXPParserTree;
  37.       const AParameters: IXPDUnitParameters;
  38.       const ABehaviours: IXPDUnitBehaviours): IXPDUnitTextTemplates;
  39. implementation
  40. uses
  41.   XPInterfacedObject,
  42.   SysUtils,
  43.   Windows;
  44. // IMPORTANT: Include resources for this unit
  45. {$R *.res}
  46. const CVSID: string = '$Header: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/DelphiExperts/DUnitProject/XPTextTemplates.pas,v 1.2 2004/05/03 15:07:16 pvspain Exp $';
  47. type
  48.   TTextTemplates = class (TXPInterfacedObject, IXPDUnitTextTemplates)
  49.   private
  50.     FTestModuleText: string;
  51.     FTestClassDeclText: string;
  52.     FTestMethodDeclText: string;
  53.     FTestSuiteRegText: string;
  54.     FUsesTestedUnitText: string;
  55.     FParameters: IXPDUnitParameters;
  56.     FBehaviours: IXPDUnitBehaviours;
  57.     FTestClasses: IXPParserTree;
  58.     function LoadTemplate(const ResourceID: PChar;
  59.       const Length: integer): string;
  60.     procedure ReplaceTestedUnitReference(var Text: string);
  61.     procedure ReplaceTestSuiteRegReference(var Text: string);
  62.     procedure ReplaceParameterReferences(var Text: string;
  63.       const TestedClassName: string = ''; const TestedMethodName: string = '');
  64.     procedure ReplaceTestMethodDeclBlockReference(var Text: string;
  65.       const ClassNode: IXPParserNode);
  66.     function ReplaceLine(var Text: string; const Pattern,
  67.       Replacement: string): boolean;
  68.   protected
  69.     function GetTestModuleText: string;
  70.     procedure ReplaceTestClassDeclBlockReference(var Text: string);
  71.   public
  72.     constructor Create(const ATestClasses: IXPParserTree;
  73.       const AParameters: IXPDUnitParameters;
  74.       const ABehaviours: IXPDUnitBehaviours;
  75.       const ADelegator: IInterface = nil);
  76.   end;
  77. function CreateXPDUnitTextTemplates(const ATestClasses: IXPParserTree;
  78.       const AParameters: IXPDUnitParameters;
  79.       const ABehaviours: IXPDUnitBehaviours): IXPDUnitTextTemplates;
  80. const
  81.   ADelelgator = nil;
  82. begin
  83.   Result := TTextTemplates.Create(ATestClasses, AParameters, ABehaviours,
  84.     ADelelgator);
  85. end;
  86. { TTextTemplates }
  87. constructor TTextTemplates.Create(const ATestClasses: IXPParserTree;
  88.   const AParameters: IXPDUnitParameters; const ABehaviours: IXPDUnitBehaviours;
  89.   const ADelegator: IInterface);
  90. begin
  91.   System.Assert((ATestClasses <> nil) and (AParameters <> nil)
  92.     and (ABehaviours <> nil));
  93.   FTestClasses := ATestClasses;
  94.   FParameters := AParameters;
  95.   FBehaviours := ABehaviours;
  96.   FTestModuleText := LoadTemplate(TestModuleTextResource,
  97.     TestModuleTextLength);
  98.   FTestClassDeclText := LoadTemplate(TestClassDeclTextResource,
  99.     TestClassDeclTextLength);
  100.   FTestMethodDeclText := LoadTemplate(TestMethodDeclTextResource,
  101.     TestMethodDeclTextLength);
  102.   FTestSuiteRegText := LoadTemplate(TestSuiteRegTextResource,
  103.     TestSuiteRegTextLength);
  104.   FUsesTestedUnitText := LoadTemplate(UsesTestedUnitTextResource,
  105.     UsesTestedUnitTextLength);
  106. end;
  107. function TTextTemplates.LoadTemplate(const ResourceID: PChar;
  108.   const Length: integer): string;
  109. begin
  110.   Result := PChar( Windows.LockResource( Windows.LoadResource(
  111.     SysInit.HInstance, Windows.FindResource( SysInit.HInstance, ResourceID,
  112.     RT_RCDATA ) ) ) );
  113.   // Remove any garbage at end of string
  114.   System.SetLength(Result, Length);
  115. end;
  116. function TTextTemplates.ReplaceLine(var Text: string;
  117.   const Pattern, Replacement: string): boolean;
  118. var
  119.   UpperText: string;
  120.   UpperPattern: string;
  121.   LineStart, LineLength: integer;
  122. begin
  123.   // Case-insensitive replacement of first occurrence of entire line
  124.   // containing Pattern with Replacement.
  125.   UpperText := SysUtils.UpperCase(Text);
  126.   UpperPattern := SysUtils.UpperCase(Pattern);
  127.   LineStart := System.Pos(UpperPattern, UpperText);
  128.   Result := LineStart > 0;
  129.   if Result then
  130.   begin
  131.     LineLength := LineStart + System.Length(Pattern);
  132.     // Search for end of previous line
  133.     while (LineStart > 0) and (Text[LineStart] <> #10) do
  134.       System.Dec(LineStart);
  135.     // Advance one char beyond EOL or to start of text
  136.     System.Inc(LineStart);
  137.     // Search for start of next line
  138.     while (LineLength <= System.Length(Text)) and (Text[LineLength] <> #10) do
  139.       System.Inc(LineLength);
  140.     // Advance beyond EOL or end of text
  141.     if (LineLength <= System.Length(Text)) then
  142.       System.Inc(LineLength);
  143.     // Final adjustment for true length
  144.     System.Dec(LineLength, LineStart);
  145.     // Replace line...
  146.     System.Delete(Text, LineStart, LineLength);
  147.     System.Insert(Replacement, Text, LineStart);
  148.   end;
  149. end;
  150. function TTextTemplates.GetTestModuleText: string;
  151. begin
  152.   // Initialise with test module code template
  153.   Result := FTestModuleText;
  154.   // Substitute DUnit parameter references
  155.   ReplaceParameterReferences(Result);
  156.   // Substitute tested unit name in uses clause
  157.   ReplaceTestedUnitReference(Result);
  158.   // Substitute test class declarations
  159.   ReplaceTestClassDeclBlockReference(Result);
  160.   // Substitute test suite registration block
  161.   ReplaceTestSuiteRegReference(Result);
  162. end;
  163. procedure TTextTemplates.ReplaceTestedUnitReference(var Text: string);
  164. var
  165.   Substitution: string;
  166. begin
  167.   // Substitution initialised to empty string implicitly..
  168.   if FBehaviours.AddCurrentToTestModule then
  169.   begin
  170.     Substitution := FUsesTestedUnitText;
  171.     // Substitute DUnit parameter references
  172.     ReplaceParameterReferences(Substitution);
  173.   end;
  174.   // Replace first line containing #USESTESTEDUNIT instance
  175.   ReplaceLine(Text, UsesTestedUnitParameter, Substitution);
  176. end;
  177. procedure TTextTemplates.ReplaceTestSuiteRegReference(var Text: string);
  178. var
  179.   Registration: string;
  180.   Registrations: string;
  181.   SectionNode: IXPParserNode;
  182.   ClassNode: IXPParserNode;
  183. begin
  184.   // Registrations intialised to empty string implicitly
  185.   // Substitute registration block
  186.   // Iterate over tested classes
  187.   FTestClasses.Children.Start;
  188.   while FTestClasses.Children.Next(SectionNode) do
  189.     if SectionNode.Enabled then
  190.     begin
  191.       SectionNode.Children.Start;
  192.       while SectionNode.Children.Next(ClassNode) do
  193.         if ClassNode.Enabled then
  194.         begin
  195.           // Prepare line to be substituted
  196.           Registration := FTestSuiteRegText;
  197.           // Substitute DUnit parameter references
  198.           ReplaceParameterReferences(Registration, ClassNode.Name);
  199.           // Add to registration statement block
  200.           Registrations := Registrations + Registration;
  201.         end;
  202.     end;
  203.   // Replace first line containing #TESTSUITEREGBLOCK instance
  204.   ReplaceLine(Text, TestSuiteRegParameter, Registrations);
  205. end;
  206. procedure TTextTemplates.ReplaceParameterReferences(var Text: string;
  207.       const TestedClassName: string; const TestedMethodName: string);
  208. var
  209.   idx: TXPDUnitParameter;
  210. const
  211.   ReplaceFlags = [rfReplaceAll, rfIgnoreCase];
  212. begin
  213.   FParameters.EvaluateValues(TestedClassName, TestedMethodName);
  214.   // Iterate over all DUnit parameters, substituting values for identifiers
  215.   // in Text.
  216.   for idx := System.Low(TXPDUnitParameter) to System.High(TXPDUnitParameter) do
  217.     Text := SysUtils.StringReplace(Text, XPDUnitParameterPrefix
  218.       + FParameters.Identifiers(idx), FParameters.Values[idx], ReplaceFlags);
  219. end;
  220. procedure TTextTemplates.ReplaceTestMethodDeclBlockReference(
  221.   var Text: string; const ClassNode: IXPParserNode);
  222. var
  223.   VisibilityNode: IXPParserNode;
  224.   MethodNode: IXPParserNode;
  225.   MethodDecl: string;
  226.   MethodDecls: string;
  227. begin
  228.   // MethodDecls intialised to empty string implicitly
  229.   // Iterate over all tested methods
  230.   ClassNode.Children.Start;
  231.   while ClassNode.Children.Next(VisibilityNode) do
  232.   begin
  233.     VisibilityNode.Children.Start;
  234.     while VisibilityNode.Children.Next(MethodNode) do
  235.     begin
  236.       // Prepare line to be substituted
  237.       MethodDecl := FTestMethodDeclText;
  238.       ReplaceParameterReferences(MethodDecl, ClassNode.Name,
  239.         MethodNode.Name);
  240.       // Add this method declaration to block
  241.       MethodDecls := MethodDecls + MethodDecl;
  242.     end;
  243.   end;
  244.   // Replace first line containing #TESTMETHODBLOCK instance
  245.   ReplaceLine(Text, TestMethodDeclParameter, MethodDecls);
  246. end;
  247. procedure TTextTemplates.ReplaceTestClassDeclBlockReference(
  248.   var Text: string);
  249. var
  250.   SectionNode: IXPParserNode;
  251.   ClassNode: IXPParserNode;
  252.   ClassDecl: string;
  253.   ClassDecls: string;
  254. begin
  255.   // ClassDecls intialised to empty string implicitly
  256.   // Iterate over all TestedUnit classes
  257.   FTestClasses.Children.Start;
  258.   while FTestClasses.Children.Next(SectionNode) do
  259.   begin
  260.     SectionNode.Children.Start;
  261.     while SectionNode.Children.Next(ClassNode) do
  262.     begin
  263.       // Prepare line to be substituted for deleted line
  264.       ClassDecl := FTestClassDeclText;
  265.       ReplaceParameterReferences(ClassDecl, ClassNode.Name);
  266.       // Replace #TESTMETHODDECLBLOCK instance
  267.       ReplaceTestMethodDeclBlockReference(ClassDecl, ClassNode);
  268.       // Add this class declaration to block
  269.       ClassDecls := ClassDecls + ClassDecl;
  270.     end;
  271.   end;
  272.   // Replace first line containing #TESTCLASSDECLBLOCK instance
  273.   ReplaceLine(Text, TestClassDeclParameter, ClassDecls);
  274. end;
  275. end.