fpc/packages/fcl-xml/tests/domunit.pp
michael 67f56b7adf * Patch from Sergei Gorelkin:
src/xmlread.pp, src/dom.pp
  * Improvements to attribute processing: attributes are now validated as
    they come. This enables reporting of the corresponding validation
    errors at correct positions (previously everything was reported at the
    end of element start-tag).
  * Search for a declaration for attribute, not for an attribute
    corresponding to the declaration. This reduces number of lookups
    (because unspecified attributes are not searched) and obsoletes the
    need in FDeclared field on every attribute.

  tests/domunit.pp, tests/testgen.pp:

  * Various improvements required to support converting of the
    DOM level 3 XPath module.

git-svn-id: trunk@12026 -
2008-11-04 18:33:05 +00:00

279 lines
8.0 KiB
ObjectPascal

{**********************************************************************
This file is part of the Free Component Library (FCL)
fpcunit extensions required to run w3.org DOM test suites
Copyright (c) 2008 by Sergei Gorelkin, sergei_gorelkin@mail.ru
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
unit domunit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, DOM, XMLRead, contnrs, fpcunit;
type
{ these two types are separated for the purpose of readability }
_collection = array of DOMString; // unordered
_list = _collection; // ordered
TDOMTestBase = class(TTestCase)
private
procedure setImplAttr(const name: string; value: Boolean);
function getImplAttr(const name: string): Boolean;
protected
// override for this one is generated by testgen for each descendant
function GetTestFilesURI: string; virtual;
protected
FParser: TDOMParser;
FAutoFree: TFPObjectList;
procedure SetUp; override;
procedure TearDown; override;
procedure GC(obj: TObject);
procedure Load(out doc: TDOMDocument; const uri: string);
function getResourceURI(const res: WideString): WideString;
function ContentTypeIs(const t: string): Boolean;
function GetImplementation: TDOMImplementation;
procedure CheckFeature(const name: string);
procedure assertNull(const id: string; const ws: DOMString); overload;
procedure assertEquals(const id: string; exp, act: TObject); overload;
procedure assertEqualsList(const id: string; const exp: array of DOMString; const act: _list);
procedure assertEqualsCollection(const id: string; const exp: array of DOMString; const act: _collection);
procedure assertSame(const id: string; exp, act: TDOMNode);
procedure assertSize(const id: string; size: Integer; obj: TDOMNodeList);
procedure assertSize(const id: string; size: Integer; obj: TDOMNamedNodeMap);
procedure assertInstanceOf(const id: string; obj: TObject; const typename: string);
procedure assertURIEquals(const id: string;
const scheme, path, host, file_, name, query, fragment: DOMString;
IsAbsolute: Boolean; const Actual: DOMString);
function bad_condition(const TagName: WideString): Boolean;
property implementationAttribute[const name: string]: Boolean read getImplAttr write setImplAttr;
end;
procedure _append(var coll: _collection; const Value: DOMString);
procedure _assign(out rslt: _collection; const value: array of DOMString);
function IsSame(exp, act: TDOMNode): Boolean;
implementation
uses
URIParser;
procedure _append(var coll: _collection; const Value: DOMString);
var
L: Integer;
begin
L := Length(coll);
SetLength(coll, L+1);
coll[L] := Value;
end;
procedure _assign(out rslt: _collection; const value: array of DOMString);
var
I: Integer;
begin
SetLength(rslt, Length(value));
for I := 0 to High(value) do
rslt[I] := value[I];
end;
function IsSame(exp, act: TDOMNode): Boolean;
begin
Result := exp = act;
end;
procedure TDOMTestBase.SetUp;
begin
FParser := TDOMParser.Create;
FParser.Options.PreserveWhitespace := True;
FAutoFree := TFPObjectList.Create(True);
end;
procedure TDOMTestBase.TearDown;
begin
FreeAndNil(FAutoFree);
FreeAndNil(FParser);
end;
procedure TDOMTestBase.GC(obj: TObject);
begin
FAutoFree.Add(obj);
end;
procedure TDOMTestBase.assertSame(const id: string; exp, act: TDOMNode);
begin
if exp <> act then
begin
assertNotNull(id, exp);
assertNotNull(id, act);
assertEquals(id, exp.nodeType, act.nodeType);
assertEquals(id, exp.nodeValue, act.nodeValue);
end;
end;
procedure TDOMTestBase.assertNull(const id: string; const ws: DOMString);
begin
if ws <> '' then
Fail(id);
end;
procedure TDOMTestBase.assertEquals(const id: string; exp, act: TObject);
begin
inherited assertSame(id, exp, act);
end;
procedure TDOMTestBase.assertEqualsList(const id: string;
const exp: array of DOMString; const act: _list);
var
I: Integer;
begin
AssertEquals(id, Length(exp), Length(act));
// compare ordered
for I := 0 to High(exp) do
AssertEquals(id, exp[I], act[I]);
end;
procedure TDOMTestBase.assertEqualsCollection(const id: string; const exp: array of DOMString; const act: _collection);
var
I, J, matches: Integer;
begin
AssertEquals(id, Length(exp), Length(act));
// compare unordered
for I := 0 to High(exp) do
begin
matches := 0;
for J := 0 to High(act) do
if act[J] = exp[I] then
Inc(matches);
AssertTrue(id+': no match found for <'+exp[I]+'>', matches <> 0);
AssertTrue(id+': multiple matches for <'+exp[I]+'>', matches = 1);
end;
end;
procedure TDOMTestBase.assertSize(const id: string; size: Integer; obj: TDOMNodeList);
begin
AssertNotNull(id, obj);
AssertEquals(id, size, obj.Length);
end;
procedure TDOMTestBase.assertSize(const id: string; size: Integer; obj: TDOMNamedNodeMap);
begin
AssertNotNull(id, obj);
AssertEquals(id, size, obj.Length);
end;
function TDOMTestBase.getResourceURI(const res: WideString): WideString;
var
Base, Level: WideString;
begin
Base := GetTestFilesURI + 'files/';
if not ResolveRelativeURI(Base, res+'.xml', Result) then
Result := '';
end;
function TDOMTestBase.getImplAttr(const name: string): Boolean;
begin
if name = 'expandEntityReferences' then
result := FParser.Options.ExpandEntities
else if name = 'validating' then
result := FParser.Options.Validate
else if name = 'namespaceAware' then
result := FParser.Options.Namespaces
else if name = 'ignoringElementContentWhitespace' then
result := not FParser.Options.PreserveWhitespace
else
begin
Fail('Unknown implementation attribute: ''' + name + '''');
result := False;
end;
end;
procedure TDOMTestBase.setImplAttr(const name: string; value: Boolean);
begin
if name = 'validating' then
FParser.Options.Validate := value
else if name = 'expandEntityReferences' then
FParser.Options.ExpandEntities := value
else if name = 'coalescing' then
// TODO: action unknown yet
else if (name = 'signed') and value then
Ignore('Setting implementation attribute ''signed'' to ''true'' is not supported')
else if name = 'hasNullString' then
// TODO: probably we cannot support this
else if name = 'namespaceAware' then
FParser.Options.Namespaces := value
else if name = 'ignoringElementContentWhitespace' then
FParser.Options.PreserveWhitespace := not value
else
Fail('Unknown implementation attribute: ''' + name + '''');
end;
procedure TDOMTestBase.Load(out doc: TDOMDocument; const uri: string);
var
t: TXMLDocument;
begin
doc := nil;
FParser.ParseURI(getResourceURI(uri), t);
doc := t;
GC(t);
end;
procedure TDOMTestBase.assertInstanceOf(const id: string; obj: TObject; const typename: string);
begin
AssertTrue(id, obj.ClassNameIs(typename));
end;
// TODO: This is a very basic implementation, needs to be completed.
procedure TDOMTestBase.assertURIEquals(const id: string; const scheme, path,
host, file_, name, query, fragment: DOMString; IsAbsolute: Boolean;
const Actual: DOMString);
var
URI: TURI;
begin
AssertTrue(id, Actual <> '');
URI := ParseURI(utf8Encode(Actual));
AssertEquals(id, URI.Document, utf8Encode(file_));
end;
function TDOMTestBase.bad_condition(const TagName: WideString): Boolean;
begin
Fail('Unsupported condition: '+ TagName);
Result := False;
end;
function TDOMTestBase.ContentTypeIs(const t: string): Boolean;
begin
{ For now, claim only xml as handled content.
This may be extended with html and svg.
}
result := (t = 'text/xml');
end;
function TDOMTestBase.GetImplementation: TDOMImplementation;
begin
result := nil;
end;
procedure TDOMTestBase.CheckFeature(const name: string);
begin
// purpose/action is currently unknown
end;
function TDOMTestBase.GetTestFilesURI: string;
begin
result := '';
end;
end.