domunit.pp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. {**********************************************************************
  2. This file is part of the Free Component Library (FCL)
  3. fpcunit extensions required to run w3.org DOM test suites
  4. Copyright (c) 2008 by Sergei Gorelkin, [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit domunit;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, DOM, XMLRead, contnrs, fpcunit;
  16. type
  17. { these two types are separated for the purpose of readability }
  18. _collection = array of DOMString; // unordered
  19. _list = _collection; // ordered
  20. TDOMTestBase = class(TTestCase)
  21. private
  22. procedure setImplAttr(const name: string; value: Boolean);
  23. function getImplAttr(const name: string): Boolean;
  24. protected
  25. // override for this one is generated by testgen for each descendant
  26. function GetTestFilesURI: string; virtual;
  27. protected
  28. FParser: TDOMParser;
  29. FAutoFree: TFPObjectList;
  30. procedure SetUp; override;
  31. procedure TearDown; override;
  32. procedure GC(obj: TObject);
  33. procedure Load(out doc: TDOMDocument; const uri: string);
  34. function getResourceURI(const res: WideString): WideString;
  35. function ContentTypeIs(const t: string): Boolean;
  36. function GetImplementation: TDOMImplementation;
  37. procedure CheckFeature(const name: string);
  38. procedure assertNull(const id: string; const ws: DOMString); overload;
  39. procedure assertEquals(const id: string; exp, act: TObject); overload;
  40. procedure assertEqualsList(const id: string; const exp: array of DOMString; const act: _list);
  41. procedure assertEqualsCollection(const id: string; const exp: array of DOMString; const act: _collection);
  42. procedure assertSame(const id: string; exp, act: TDOMNode);
  43. procedure assertSize(const id: string; size: Integer; obj: TDOMNodeList);
  44. procedure assertSize(const id: string; size: Integer; obj: TDOMNamedNodeMap);
  45. procedure assertInstanceOf(const id: string; obj: TObject; const typename: string);
  46. procedure assertURIEquals(const id: string;
  47. const scheme, path, host, file_, name, query, fragment: DOMString;
  48. IsAbsolute: Boolean; const Actual: DOMString);
  49. function bad_condition(const TagName: WideString): Boolean;
  50. property implementationAttribute[const name: string]: Boolean read getImplAttr write setImplAttr;
  51. end;
  52. procedure _append(var coll: _collection; const Value: DOMString);
  53. procedure _assign(out rslt: _collection; const value: array of DOMString);
  54. implementation
  55. uses
  56. URIParser;
  57. procedure _append(var coll: _collection; const Value: DOMString);
  58. var
  59. L: Integer;
  60. begin
  61. L := Length(coll);
  62. SetLength(coll, L+1);
  63. coll[L] := Value;
  64. end;
  65. procedure _assign(out rslt: _collection; const value: array of DOMString);
  66. var
  67. I: Integer;
  68. begin
  69. SetLength(rslt, Length(value));
  70. for I := 0 to High(value) do
  71. rslt[I] := value[I];
  72. end;
  73. procedure TDOMTestBase.SetUp;
  74. begin
  75. FParser := TDOMParser.Create;
  76. FParser.Options.PreserveWhitespace := True;
  77. FAutoFree := TFPObjectList.Create(True);
  78. end;
  79. procedure TDOMTestBase.TearDown;
  80. begin
  81. FreeAndNil(FAutoFree);
  82. FreeAndNil(FParser);
  83. end;
  84. procedure TDOMTestBase.GC(obj: TObject);
  85. begin
  86. FAutoFree.Add(obj);
  87. end;
  88. procedure TDOMTestBase.assertSame(const id: string; exp, act: TDOMNode);
  89. begin
  90. if exp <> act then
  91. begin
  92. assertNotNull(id, exp);
  93. assertNotNull(id, act);
  94. assertEquals(id, exp.nodeType, act.nodeType);
  95. assertEquals(id, exp.nodeValue, act.nodeValue);
  96. end;
  97. end;
  98. procedure TDOMTestBase.assertNull(const id: string; const ws: DOMString);
  99. begin
  100. if ws <> '' then
  101. Fail(id);
  102. end;
  103. procedure TDOMTestBase.assertEquals(const id: string; exp, act: TObject);
  104. begin
  105. inherited assertSame(id, exp, act);
  106. end;
  107. procedure TDOMTestBase.assertEqualsList(const id: string;
  108. const exp: array of DOMString; const act: _list);
  109. var
  110. I: Integer;
  111. begin
  112. AssertEquals(id, Length(exp), Length(act));
  113. // compare ordered
  114. for I := 0 to High(exp) do
  115. AssertEquals(id, exp[I], act[I]);
  116. end;
  117. procedure TDOMTestBase.assertEqualsCollection(const id: string; const exp: array of DOMString; const act: _collection);
  118. var
  119. I, J, matches: Integer;
  120. begin
  121. AssertEquals(id, Length(exp), Length(act));
  122. // compare unordered
  123. for I := 0 to High(exp) do
  124. begin
  125. matches := 0;
  126. for J := 0 to High(act) do
  127. if act[J] = exp[I] then
  128. Inc(matches);
  129. AssertTrue(id+': no match found for <'+exp[I]+'>', matches <> 0);
  130. AssertTrue(id+': multiple matches for <'+exp[I]+'>', matches = 1);
  131. end;
  132. end;
  133. procedure TDOMTestBase.assertSize(const id: string; size: Integer; obj: TDOMNodeList);
  134. begin
  135. AssertNotNull(id, obj);
  136. AssertEquals(id, size, obj.Length);
  137. end;
  138. procedure TDOMTestBase.assertSize(const id: string; size: Integer; obj: TDOMNamedNodeMap);
  139. begin
  140. AssertNotNull(id, obj);
  141. AssertEquals(id, size, obj.Length);
  142. end;
  143. function TDOMTestBase.getResourceURI(const res: WideString): WideString;
  144. var
  145. Base, Level: WideString;
  146. begin
  147. Base := GetTestFilesURI + 'files/';
  148. if not ResolveRelativeURI(Base, res+'.xml', Result) then
  149. Result := '';
  150. end;
  151. function TDOMTestBase.getImplAttr(const name: string): Boolean;
  152. begin
  153. if name = 'expandEntityReferences' then
  154. result := FParser.Options.ExpandEntities
  155. else if name = 'validating' then
  156. result := FParser.Options.Validate
  157. else if name = 'namespaceAware' then
  158. result := FParser.Options.Namespaces
  159. else if name = 'ignoringElementContentWhitespace' then
  160. result := not FParser.Options.PreserveWhitespace
  161. else
  162. begin
  163. Fail('Unknown implementation attribute: ''' + name + '''');
  164. result := False;
  165. end;
  166. end;
  167. procedure TDOMTestBase.setImplAttr(const name: string; value: Boolean);
  168. begin
  169. if name = 'validating' then
  170. FParser.Options.Validate := value
  171. else if name = 'expandEntityReferences' then
  172. FParser.Options.ExpandEntities := value
  173. else if name = 'coalescing' then
  174. // TODO: action unknown yet
  175. else if (name = 'signed') and value then
  176. Ignore('Setting implementation attribute ''signed'' to ''true'' is not supported')
  177. else if name = 'hasNullString' then
  178. // TODO: probably we cannot support this
  179. else if name = 'namespaceAware' then
  180. FParser.Options.Namespaces := value
  181. else if name = 'ignoringElementContentWhitespace' then
  182. FParser.Options.PreserveWhitespace := not value
  183. else
  184. Fail('Unknown implementation attribute: ''' + name + '''');
  185. end;
  186. procedure TDOMTestBase.Load(out doc: TDOMDocument; const uri: string);
  187. var
  188. t: TXMLDocument;
  189. begin
  190. doc := nil;
  191. FParser.ParseURI(getResourceURI(uri), t);
  192. doc := t;
  193. GC(t);
  194. end;
  195. procedure TDOMTestBase.assertInstanceOf(const id: string; obj: TObject; const typename: string);
  196. begin
  197. AssertTrue(id, obj.ClassNameIs(typename));
  198. end;
  199. // TODO: This is a very basic implementation, needs to be completed.
  200. procedure TDOMTestBase.assertURIEquals(const id: string; const scheme, path,
  201. host, file_, name, query, fragment: DOMString; IsAbsolute: Boolean;
  202. const Actual: DOMString);
  203. var
  204. URI: TURI;
  205. begin
  206. AssertTrue(id, Actual <> '');
  207. URI := ParseURI(utf8Encode(Actual));
  208. AssertEquals(id, URI.Document, utf8Encode(file_));
  209. end;
  210. function TDOMTestBase.bad_condition(const TagName: WideString): Boolean;
  211. begin
  212. Fail('Unsupported condition: '+ TagName);
  213. Result := False;
  214. end;
  215. function TDOMTestBase.ContentTypeIs(const t: string): Boolean;
  216. begin
  217. { For now, claim only xml as handled content.
  218. This may be extended with html and svg.
  219. }
  220. result := (t = 'text/xml');
  221. end;
  222. function TDOMTestBase.GetImplementation: TDOMImplementation;
  223. begin
  224. result := nil;
  225. end;
  226. procedure TDOMTestBase.CheckFeature(const name: string);
  227. begin
  228. // purpose/action is currently unknown
  229. end;
  230. function TDOMTestBase.GetTestFilesURI: string;
  231. begin
  232. result := '';
  233. end;
  234. end.