unit uXSLTPattern;

{$I XpDefine.inc}

interface
uses
  TestFramework,
  SysUtils,
  Classes,
{$IFDEF WIN32}
  Forms,
  Windows,
{$ENDIF}
  XpParser,
  XpDOM,
  XpBase,
{$IFDEF UsingCLX}
  XpQXSLT,
  XpQFlXML;
{$ELSE}
  XpvXSLT,
  XpvFlXML;
{$ENDIF}


type
  TXpXSLTPatterns = class(TTestCase)
  protected
    FDOM : TXpObjModel;
    FPatternMaker : TXpPatternMaker;
    procedure LoadDoc(const aFileName : string);
      { Load an XML document located in the ..\Data\Patterns subfolder. }

    procedure Setup; override;
    procedure Teardown; override;
  public
  published
    procedure TestCertainFailure;
    procedure TestDescendant;
    procedure TestInvalidPatterns;
    procedure TestLocationPath;
    procedure TestNamespace;
    procedure TestNodeType;
    procedure TestPredicates;
    procedure TestRoot;
    procedure TestUnion;
    procedure TestWildcard;
  end;

implementation

uses
  XpExcept;

const
  { test documents }
  csDoc1 = 'doc1.xml';
  csDoc2 = 'doc2.xml';
  csDoc2XSL = 'doc2.xsl';

{=====================================================================}
procedure TXpXSLTPatterns.LoadDoc(const aFileName : string);
var
  aFileSpec : string;
begin
  { Assumes that all documents are located in ..\Data\Patterns. }
{$IFDEF WIN32}
  aFileSpec := '..\data\patterns\' + ExtractFileName(aFileName);
{$ENDIF}
{$IFDEF LINUX}
  aFileSpec := '../data/patterns/' + ExtractFileName(aFileName);
{$ENDIF}

  if not FDOM.LoadDataSource(aFileSpec) then
    Assert(False, Format('Could not load document %s', [aFileSpec]));
end;
{--------}
procedure TXpXSLTPatterns.Setup;
begin
  FDOM := TXpObjModel.Create(nil);
  FPatternMaker := TXpPatternMaker.Create;
end;
{--------}
procedure TXpXSLTPatterns.Teardown;
begin
  FDOM.Free;
  FPatternMaker.Free;
end;
{--------}
procedure TXpXSLTPatterns.TestCertainFailure;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);
  oPattern := FPatternMaker.GeneratePattern(nil, '@text()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1d failed');
    oNode := oNode.FirstChild.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 1e failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, '@comment()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2d failed');
    oNode := oNode.FirstChild.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 2e failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, '@processing-instruction()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3d failed');
    oNode := oNode.FirstChild.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 3e failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, '@processing-instruction("test")');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4d failed');
    oNode := oNode.FirstChild.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 4e failed');
  finally
    oPattern.Free;
  end;

end;
{--------}
procedure TXpXSLTPatterns.TestDescendant;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);
  oPattern := FPatternMaker.GeneratePattern(nil, '//C');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 1d failed');
    oNode := oNode.FirstChild.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 1e failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, 'root//D');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2c failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2d failed');
    oNode := oNode.FirstChild.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 2e failed');
    oNode := oNode.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 2f failed');
  finally
    oPattern.Free;
  end;

end;
{--------}
procedure TXpXSLTPatterns.TestInvalidPatterns;
var
  bExceptRaised : Boolean;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);

  { Slash required }
  bExceptRaised := False;
  oPattern := nil;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'A)');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  oPattern := nil;
  Assert(bExceptRaised, 'Slash required test failed');

  { Right paren required }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'node(');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  oPattern := nil;
  Assert(bExceptRaised, 'Right paren required test failed');

  { Unexpected token }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'A | | B');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Unexpected token test failed');

  { Literal required }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'id()');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Literal required test failed');

  { No functions allowed except for id() or key() }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'position()');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'No function test failed');

  { Invalid axis }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'ancestor::root');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Invalid axis test failed');

  { Non-literal in PI }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'processing-instruction(node())');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Non-literal in PI test failed');

  { Non-literal in @PI }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, '@processing-instruction(node())');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Non-literal in @PI test failed');

  { Unexpected attrib token }
  bExceptRaised := False;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, '@!');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  oPattern.Free;
  Assert(bExceptRaised, 'Unexpected attrib token test failed');

end;
{--------}
procedure TXpXSLTPatterns.TestLocationPath;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);
  oPattern := FPatternMaker.GeneratePattern(nil, 'C/D');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 1c failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, 'A');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 2c failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, '/root/A');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3b failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 3c failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, 'child::A');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4b failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 4c failed');
  finally
    oPattern.Free;
  end;

end;
{--------}
procedure TXpXSLTPatterns.TestNamespace;
var
  bExceptRaised : Boolean;
  oPattern : TXpPattern;
  oAttrNode, oNode : TXpNode;
  oXSLDOM : TXpObjModel;
begin
  LoadDoc(csDoc2);
  oXSLDOM := TXpObjModel.Create(nil);
  try
{$IFDEF WIN32}
    Assert(oXSLDOM.LoadDataSource('..\data\patterns\' + csDoc2XSL),
           'Could not load XSL stylesheet');
{$ENDIF}
{$IFDEF LINUX}
    Assert(oXSLDOM.LoadDataSource('../data/patterns/' + csDoc2XSL),
           'Could not load XSL stylesheet');
{$ENDIF}

    { Namespace test on element. }
    oPattern := FPatternMaker.GeneratePattern
                (TXpBaseXSLElement(oXSLDOM.Document.DocumentElement.FirstChild),
                 'tps:B');
    try
      oNode := FDOM.Document;
      Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
      oNode := FDOM.Document.DocumentElement.FirstChild;
      Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
      oNode := oNode.FirstChild;
      Assert(oPattern.Matches(oNode, nil), 'Test 1c failed');
    finally
      oPattern.Free;
    end;

    { Namespace test on attribute. }
    oPattern := FPatternMaker.GeneratePattern
                (TXpBaseXSLElement(oXSLDOM.Document.DocumentElement.FirstChild),
                 '@tps:ID');
    try
      oNode := FDOM.Document;
      Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
      oNode := FDOM.Document.DocumentElement.FirstChild;
      Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
      oNode := oNode.FirstChild;
      Assert(not oPattern.Matches(oNode, nil), 'Test 2c failed');
      oAttrNode := oNode.Attributes.Item(0);
      Assert(oPattern.Matches(oAttrNode, nil), 'Test 2d failed');
      oNode := oNode.NextSibling;
      oAttrNode := oNode.Attributes.Item(0);
      Assert(not oPattern.Matches(oAttrNode, nil), 'Test 2e failed');
    finally
      oPattern.Free;
    end;

    { Unresolved namespace. }
    bExceptRaised := False;
    oPattern := nil;
    try
      oPattern := FPatternMaker.GeneratePattern
                  (TXpBaseXSLElement(oXSLDOM.Document.DocumentElement.FirstChild),
                   'xbv:B');
    except
      on E:EXpException do
        bExceptRaised := True;
    end;
    oPattern.Free;
    Assert(bExceptRaised, 'Test 3 failed');

  finally
    oXSLDOM.Free;
  end;
end;
{--------}
procedure TXpXSLTPatterns.TestNodeType;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);

  { Test node(). }
  oPattern := FPatternMaker.GeneratePattern(nil, 'node()');
  try
    oNode := FDOM.Document;
    Assert(oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(oPattern.Matches(oNode, nil), 'Test 1d failed');
  finally
    oPattern.Free;
  end;

  { Test @node(). }
  oPattern := FPatternMaker.GeneratePattern(nil, '@node()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(oPattern.Matches(oNode, nil), 'Test 2d failed');
  finally
    oPattern.Free;
  end;

  { Test comment(). }
  oPattern := FPatternMaker.GeneratePattern(nil, 'comment()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(oPattern.Matches(oNode, nil), 'Test 3b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 3d failed');
  finally
    oPattern.Free;
  end;

  { Test text(). }
  oPattern := FPatternMaker.GeneratePattern(nil, 'text()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 4b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(oPattern.Matches(oNode, nil), 'Test 4c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 4d failed');
  finally
    oPattern.Free;
  end;

  { Test processing-instruction() }
  oPattern := FPatternMaker.GeneratePattern(nil, 'processing-instruction()');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 5a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 5b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 5c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 5d failed');
    oNode := FDOM.Document.DocumentElement.LastChild;
    Assert(oPattern.Matches(oNode, nil), 'Test 5e failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, 'processing-instruction("AProcInst")');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 6a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 6b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 6c failed');
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 6d failed');
    oNode := FDOM.Document.DocumentElement.LastChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 6e failed');
    oNode := oNode.PreviousSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 6f failed');
  finally
    oPattern.Free;
  end;

end;
{--------}
procedure TXpXSLTPatterns.TestPredicates;
var
  bExceptRaised : Boolean;
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);
  { Match any A element that is the first A child element of its parent. }
  oPattern := FPatternMaker.GeneratePattern(nil, 'A[1]');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 1a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 1b failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Pred test 1c failed');
  finally
    oPattern.Free;
  end;

  { Match any A element that is the second A child element of its parent. }
  oPattern := FPatternMaker.GeneratePattern(nil, 'A[2]');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 2a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 2b failed');
    oNode := oNode.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 2c failed');
  finally
    oPattern.Free;
  end;

  { Match any D element having an ID & Name attributes. }
  oPattern := FPatternMaker.GeneratePattern(nil, 'D[@ID and @Name]');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 3a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 3b failed');
    oNode := oNode.NextSibling; { A }
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 3c failed');
    oNode := oNode.NextSibling.NextSibling.FirstChild.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Pred test 3d failed');
    oNode := oNode.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Pred test 3e failed');
  finally
    oPattern.Free;
  end;

  { Predicate missing a right brace. }
  bExceptRaised := False;
  oPattern := nil;
  try
    oPattern := FPatternMaker.GeneratePattern(nil, 'A[2');
  except
    on E:EXpException do
      bExceptRaised := True;
  end;
  Assert(bExceptRaised, 'Pred test 4 failed');
  oPattern.Free;
end;
{--------}
procedure TXpXSLTPatterns.TestRoot;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);
  oPattern := FPatternMaker.GeneratePattern(nil, '/');
  try
    oNode := FDOM.Document;
    Assert(oPattern.Matches(oNode, nil), 'Root test 1 failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Root test 2 failed');
  finally
    oPattern.Free;
  end;
end;
{--------}
procedure TXpXSLTPatterns.TestUnion;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);

  oPattern := FPatternMaker.GeneratePattern(nil, 'A | B | D | @ID');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling;  { A }
    Assert(oPattern.Matches(oNode, nil), 'Test 1d failed');
    oNode := oNode.NextSibling;  { B }
    Assert(oPattern.Matches(oNode, nil), 'Test 1e failed');
    oNode := oNode.NextSibling.FirstChild.NextSibling;  { D }
    Assert(oPattern.Matches(oNode, nil), 'Test 1f failed');
    oNode := oNode.Attributes.GetNamedItem('ID');
    Assert(oPattern.Matches(oNode, nil), 'Test 1g failed');
    oNode := oNode.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1h failed');
  finally
    oPattern.Free;
  end;

  oPattern := FPatternMaker.GeneratePattern(nil, '/ | A');
  try
    oNode := FDOM.Document;
    Assert(oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling;  { A }
    Assert(oPattern.Matches(oNode, nil), 'Test 1d failed');
    oNode := oNode.NextSibling;  { B }
    Assert(not oPattern.Matches(oNode, nil), 'Test 1e failed');
    oNode := oNode.NextSibling.FirstChild.NextSibling;  { D }
    Assert(not oPattern.Matches(oNode, nil), 'Test 1f failed');
    oNode := oNode.Attributes.GetNamedItem('ID');
    Assert(not oPattern.Matches(oNode, nil), 'Test 1g failed');
    oNode := oNode.NextSibling;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1h failed');
  finally
    oPattern.Free;
  end;
end;
{--------}
procedure TXpXSLTPatterns.TestWildcard;
var
  oNode : TXpNode;
  oPattern : TXpPattern;
begin
  LoadDoc(csDoc1);

  { Verify wildcard pattern for elements. }
  oPattern := FPatternMaker.GeneratePattern(nil, '*');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1b failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 1c failed');
    oNode := oNode.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1d failed');
    oNode := oNode.NextSibling;
    Assert(oPattern.Matches(oNode, nil), 'Test 1e failed');
    oNode := oNode.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 1f failed');

    { Verify that an attribute will not match. }
    oNode := FDOM.Document.DocumentElement;
    oNode := oNode.FirstChild.NextSibling.NextSibling.NextSibling.FirstChild;
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(not oPattern.Matches(oNode, nil), 'Test 1e failed');
  finally
    oPattern.Free;
  end;

  { Verify wildcard pattern for attributes. }
  oPattern := FPatternMaker.GeneratePattern(nil, '@*');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 2c failed');

    { Verify that an attribute will not match. }
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(oPattern.Matches(oNode, nil), 'Test 2d failed');
  finally
    oPattern.Free;
  end;

    { Verify wildcard pattern for attributes. }
  oPattern := FPatternMaker.GeneratePattern(nil, 'attribute::*');
  try
    oNode := FDOM.Document;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3a failed');
    oNode := FDOM.Document.DocumentElement.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3b failed');
    oNode := oNode.NextSibling.NextSibling.NextSibling.FirstChild;
    Assert(not oPattern.Matches(oNode, nil), 'Test 3c failed');

    { Verify that an attribute will not match. }
    oNode := oNode.NextSibling.Attributes.GetNamedItem('ID');
    Assert(oNode <> nil, 'Could not get attribute node');
    Assert(oPattern.Matches(oNode, nil), 'Test 3d failed');
  finally
    oPattern.Free;
  end;

end;
{=====================================================================}

initialization
  RegisterTest('XSL Pattern Tests', TXpXSLTPatterns);
end.
