{ Test all with: ./runtests --format=plain --suite=TTestLazXML Test specific with: ./runtests --format=plain --suite=TestStrToXMLValue ./runtests --format=plain --suite=TestXMLValueToStr ./runtests --format=plain --suite=TestTranslateUTF8Chars ./runtests --format=plain --suite=TestXPath } unit TestLazXML; {$mode objfpc}{$H+} interface uses Classes, SysUtils, fpcunit, testglobals, laz2_DOM, laz2_xmlutils, laz2_xpath, laz2_XMLRead, LazLogger; type { TTestLazXML } TTestLazXML = class(TTestCase) public published procedure TestStrToXMLValue; procedure TestXMLValueToStr; procedure TestTranslateUTF8Chars; procedure TestXPath; end; implementation { TTestLazXML } procedure TTestLazXML.TestStrToXMLValue; begin AssertEquals('Empty string','',StrToXMLValue('')); AssertEquals('Short string','a',StrToXMLValue('a')); AssertEquals('String with #0','',StrToXMLValue(#0)); AssertEquals('String with &','&',StrToXMLValue('&')); AssertEquals('String with <','<',StrToXMLValue('<')); AssertEquals('String with >','>',StrToXMLValue('>')); AssertEquals('String with ''',''',StrToXMLValue('''')); AssertEquals('String with "','"',StrToXMLValue('"')); AssertEquals('String mix 1','<a>"',StrToXMLValue(''#0'"')); AssertEquals('String mix 2','abc',StrToXMLValue('abc')); end; procedure TTestLazXML.TestXMLValueToStr; begin AssertEquals('Empty string','',XMLValueToStr('')); AssertEquals('Short string a','a',XMLValueToStr('a')); AssertEquals('Short string #0',#0,XMLValueToStr(#0)); AssertEquals('Short string abc','abc',XMLValueToStr('abc')); AssertEquals('String with &','&',XMLValueToStr('&')); AssertEquals('String with <','<',XMLValueToStr('<')); AssertEquals('String with >','>',XMLValueToStr('>')); AssertEquals('String with ''','''',XMLValueToStr(''')); AssertEquals('String with "','"',XMLValueToStr('"')); AssertEquals('String mix "','"',XMLValueToStr('<a>"')); end; procedure TTestLazXML.TestTranslateUTF8Chars; procedure T(Title, s, SrcChars, DstChars, Expected: string); var h: String; begin h:=s; TranslateUTF8Chars(h,SrcChars,DstChars); if h=Expected then exit; AssertEquals(Title+': s="'+s+'" SrcChars="'+SrcChars+'" DstChars="'+DstChars+'"',Expected,h); end; begin T('empty','','','',''); T('nop','a','b','b','a'); T('a to b','a','a','b','b'); T('switch a,b','abaa','ab','ba','babb'); T('delete a','a','a','',''); T('delete a','aba','a','','b'); T('replace ä with ö','bä','ä','ö','bö'); T('replace ä with ö','äbä','ä','ö','öbö'); T('switch ä,ö','äbö','äö','öä','öbä'); T('delete ä','äbö','ä','','bö'); T('replace ä with a','äbö','ä','a','abö'); end; procedure TTestLazXML.TestXPath; procedure CheckNode(Node: TDOMElement; XPath: string; ExpCount: integer; ExpFirstTagName: string); var V: TXPathVariable; FirstNode: TDOMElement; begin V:=nil; try V:=EvaluateXPathExpression(XPath,Node); AssertEquals('xpath="'+XPath+'": AsNodeSet',True,V.AsNodeSet<>nil); AssertEquals('xpath="'+XPath+'": AsNodeSet.Count',ExpCount,V.ASNodeSet.Count); if V.ASNodeSet.Count=0 then exit; FirstNode:=TDOMElement(V.AsNodeSet[0]); if ExpFirstTagName<>'' then begin AssertEquals('xpath="'+XPath+'": node',ExpFirstTagName,FirstNode.TagName); end; finally V.Free; end; end; var xml: String; ss: TStringStream; Doc: TXMLDocument; BookStoreNode: TDOMElement; V: TXPathVariable; NodeSet: TNodeSet; Node: TDOMElement; begin xml:=''+LineEnding +''+LineEnding +' '+LineEnding +' Lazarus'+LineEnding +' '+LineEnding +' '+LineEnding +' Felipe Monteiro de Carvalho'+LineEnding +' '+LineEnding +' 2011'+LineEnding +' 37,50'+LineEnding +' '+LineEnding +''+LineEnding; Doc:=nil; V:=nil; ss:=TStringStream.Create(xml); try ReadXMLFile(Doc,ss); BookStoreNode:=Doc.DocumentElement; // CheckNode return type V:=EvaluateXPathExpression('/bookstore',BookStoreNode); //debugln(['TTestLazXML.TestXPath ',dbgsname(V)]); AssertEquals('/bookstore returns class',TXPathNodeSetVariable,V.ClassType); NodeSet:=V.AsNodeSet; AssertEquals('/bookstore AsNodeSet',True,NodeSet<>nil); AssertEquals('/bookstore AsNodeSet.Count',1,NodeSet.Count); Node:=TDOMElement(NodeSet[0]); AssertEquals('/bookstore AsNodeSet[0] class',TDOMElement,Node.ClassType); AssertEquals('/bookstore node',True,Node=BookStoreNode); FreeAndNil(V); // CheckNode // CheckNode(BookStoreNode,'book',1,'book'); CheckNode(BookStoreNode,'//book',1,'book'); CheckNode(BookStoreNode,'book/title',1,'title'); CheckNode(BookStoreNode,'book/author',4,'author'); CheckNode(BookStoreNode,'book//title',1,'title'); CheckNode(BookStoreNode,'book/author[@forename=''Mattias'']',1,'author'); CheckNode(BookStoreNode,'book/author[@surname=''Gaertner'']',1,'author'); CheckNode(BookStoreNode,'book/author[@forename=''Mattias'' and @surname=''Gaertner'']',1,'author'); CheckNode(BookStoreNode,'book/author[2]',1,'author'); CheckNode(BookStoreNode,'book/author[2][1]',1,'author'); CheckNode(BookStoreNode,'book/author[2][@forename=''Mattias'']',1,'author'); CheckNode(BookStoreNode,'book/author[last()]',1,'author'); CheckNode(BookStoreNode,'book/author[last()-1]',1,'author'); CheckNode(BookStoreNode,'book/author[last()-1][@forename=''Felipe'']',1,'author'); CheckNode(BookStoreNode,'book[year>2000]',1,'book'); CheckNode(BookStoreNode,'book/*[@forename]',4,'author'); CheckNode(BookStoreNode,'book/title|book/price',2,'title'); finally V.Free; Doc.Free; ss.Free; end; end; initialization AddToLazUtilsTestSuite(TTestLazXML); end.