понедельник, 16 марта 2015 г.

GUI-testing 10. GUI-testing “in the spoken style”. Note about “how this thing is organized”

Original in Russian: http://18delphi.blogspot.ru/2013/11/gui_5.html

GUI-testing. Table of contents

Now, a couple of words about how it is organized.

(I’m writing “at sight” from memory.)

We have a parser that parsers the input stream for tokens.

The parser interface is something like this:

type
 TscriptTokenType = (ttInteger, ttString, ttKeyWord);
 
 IscriptParser = interface
  function IsEOF : Boolean;
  procedure NextToken;
  function TokenType: TscriptTokenType;
  function IntegerToken: Integer;
  function StringToken: String;
  function KeyWordToken: TscriptKeyWord;
 end;//IscriptParser

We have a script engine that parsers text using parser and compiles it.

The main procedure of the script engine is something like this:

type
  TscriptContext = class
   function PopInteger: Integer;
   procedure PushInteger(aValue : Integer);
   function PopString: String;
   procedure PushString(const aValue : String);
   function PopObject: TObject;
   procedure PushObject(aValue : TObject);
   ...
  end;//TscriptContext
   
  TscriptKeyWord = class
   function IsImmediate: Boolean; virtual;
    {* - is the word DIRECTLY executed? Like PROCEDURE, FUNCTION, VAR, CONST, etc. }
   procedure DoIt(aContext: TscriptContext); virtual; abstract;
    {* - the code of word execution. }
  end;//TscriptKeyWord
 
  TscriptCode = class
   procedure CompileInteger(aValue: Integer);
   procedure CompileString(const aValue: String);
   procedure CompileKeyWord(aValue: TscriptKeyWord);
   procedure Run; // - executes the compiled code
   procedure RunInContext(aContext: TscriptContext); // - executes the compiled code in the specified context
   ...
  end;//TscriptCode
   
  TscriptCompileContext = class(TscriptContext)
   property Parser: IscriptParser;
    {* - The current parcer. }
   property Code: TscriptCode;
    {* - The current compiled code. }
  end;//TscriptCompileContext
 
procedure TscriptEngine.Compile(const aParser : IscriptParser; aCode : TscriptCode);
var
 l_Context : TscriptCompileContext;
begin
 l_Context := TscriptCompileContext.Create;
 try
  l_Context.Parser := aParser; 
  // - So that words of DIRECT execution could be executed and the current parser could be managed
  l_Context.Code := aCode; // - place where the code is compiled to
  while not aParser.IsEOF do
  begin
   Case aParser.TokenType of
    ttInteger : 
     aCode.CompileInteger(aParser.IntegerToken); // - we compile the integer
    ttStringr : 
     aCode.CompileString(aParser.StringToken); // - we compile the string
    ttKeyWord :
    begin
     if aParser.KeyWordToken.IsImmediate then
      // - the word of DIRECT execution like PROCEDURE, FUNCTION, VAR, CONST, etc. 
      //   (“user” words – can also be like this)
      aParser.KeyWordToken.DoIt(l_Context) 
      // - we execute the word in context of compilation, 
      //   at the same time such words can manage either parser or the compiled code
     else
      aCode.CompileKeyWord(aParser.KeyWordToken); // - we compile the word call
    end;//ttKeyWord
    else
     Assert(false); // - in case it appears (by the way, it exists)
   end;//Case aParser.TokenType
   aParser.NextToken;
  end;//while not aParser.IsEOF
 finally
  FreeAndNil(l_Context);
 end;//try..finally
end;//TscriptEngine.Compile

The process of compilation and launch:

procedure RunCode(const aParser : IscriptParser);
var
 l_Code : TscriptCode;
 l_ScriptEngine : TscriptEngine;
begin
 l_Code := TscriptCode.Create;
 try
  l_ScriptEngine := TscriptEngine.Create;
  try
   l_ScriptEngine.Compile(aParser, l_Code);
   // - we compile the code from the input stream
  finally
   FreeAndNil(l_ScriptEngine);
  end;//try..finally
  l_Code.Run; 
  // - the code can be executed at once, 
  //   but, in general, it can be saved in some outer object 
  //   and executed a number of times
 finally
  FreeAndNil(l_Code);
 end;//try..finally
end;

To be continued, for sure. I have already written a plan of 8 more articles. I hope that “at the end of the path” the interested readers will be able to compile the script/test engine of the parts.

Комментариев нет:

Отправить комментарий