extras.pp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. {**********************************************************************
  2. This file is part of the Free Component Library (FCL)
  3. DOM Test cases which are missing from w3.org test suite
  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 extras;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. SysUtils, Classes, DOM, xmlread, xmlwrite, domunit, testregistry;
  16. implementation
  17. type
  18. TDOMTestExtra = class(TDOMTestBase)
  19. published
  20. procedure attr_ownership01;
  21. procedure attr_ownership02;
  22. procedure attr_ownership03;
  23. procedure attr_ownership04;
  24. procedure attr_ownership05;
  25. procedure replacesamechild;
  26. procedure nsFixup1;
  27. procedure nsFixup2;
  28. procedure nsFixup3;
  29. end;
  30. { TDOMTestExtra }
  31. // verify that an attribute created by Element.SetAttribute()
  32. // has its OwnerElement assigned properly
  33. procedure TDOMTestExtra.attr_ownership01;
  34. var
  35. doc: TDOMDocument;
  36. el: TDOMElement;
  37. attr: TDOMAttr;
  38. attrOwner: TDOMElement;
  39. begin
  40. LoadStringData(doc, '<doc/>');
  41. el := doc.CreateElement('element1');
  42. el.SetAttribute('newAttr', 'newValue');
  43. attr := el.GetAttributeNode('newAttr');
  44. AssertNotNull('attribute', attr);
  45. attrOwner := attr.OwnerElement;
  46. AssertEquals('ownerElement', el, attrOwner);
  47. AssertTrue('specified', attr.Specified);
  48. end;
  49. // verify that an attribute created by Element.SetAttributeNS()
  50. // has its OwnerElement assigned properly
  51. procedure TDOMTestExtra.attr_ownership02;
  52. var
  53. doc: TDOMDocument;
  54. el: TDOMElement;
  55. attr: TDOMAttr;
  56. attrOwner: TDOMElement;
  57. begin
  58. LoadStringData(doc, '<doc/>');
  59. el := doc.CreateElement('element1');
  60. el.SetAttributeNS('http://www.freepascal.org', 'fpc:newAttr', 'newValue');
  61. attr := el.GetAttributeNodeNS('http://www.freepascal.org', 'newAttr');
  62. AssertNotNull('attribute', attr);
  63. attrOwner := attr.OwnerElement;
  64. AssertEquals('ownerElement', el, attrOwner);
  65. AssertTrue('specified', attr.Specified);
  66. end;
  67. // verify that NamedNodeMap.SetNamedItem() resets OwnerElement
  68. // of the attribute being replaced
  69. procedure TDOMTestExtra.attr_ownership03;
  70. var
  71. doc: TDOMDocument;
  72. el: TDOMElement;
  73. attr, attr2: TDOMAttr;
  74. retNode: TDOMNode;
  75. begin
  76. LoadStringData(doc, '<doc/>');
  77. el := doc.CreateElement('element1');
  78. attr := doc.CreateAttribute('newAttr');
  79. el.SetAttributeNode(attr);
  80. AssertEquals('ownerElement_before', el, attr.OwnerElement);
  81. attr2 := doc.CreateAttribute('newAttr');
  82. retNode := el.Attributes.SetNamedItem(attr2);
  83. AssertSame('retNode', attr, retNode);
  84. AssertNull('ownerElement_after', attr.OwnerElement);
  85. AssertEquals('ownerElement2', el, attr2.OwnerElement);
  86. end;
  87. // verify that NamedNodeMap.SetNamedItemNS() resets OwnerElement
  88. // of the attribute being replaced
  89. procedure TDOMTestExtra.attr_ownership04;
  90. var
  91. doc: TDOMDocument;
  92. el: TDOMElement;
  93. attr, attr2: TDOMAttr;
  94. retNode: TDOMNode;
  95. begin
  96. LoadStringData(doc, '<doc/>');
  97. el := doc.CreateElement('element1');
  98. attr := doc.CreateAttributeNS('http://www.freepascal.org', 'fpc:newAttr');
  99. el.SetAttributeNodeNS(attr);
  100. AssertEquals('ownerElement_before', el, attr.OwnerElement);
  101. attr2 := doc.CreateAttributeNS('http://www.freepascal.org', 'fpc:newAttr');
  102. retNode := el.Attributes.SetNamedItemNS(attr2);
  103. AssertSame('retNode', attr, retNode);
  104. AssertNull('ownerElement_after', attr.OwnerElement);
  105. AssertEquals('ownerElement2', el, attr2.OwnerElement);
  106. end;
  107. // verify that Element.removeAttributeNode() resets ownerElement
  108. // of the attribute being removed
  109. procedure TDOMTestExtra.attr_ownership05;
  110. var
  111. doc: TDOMDocument;
  112. el: TDOMElement;
  113. attr: TDOMAttr;
  114. begin
  115. LoadStringData(doc, '<doc/>');
  116. el := doc.CreateElement('element1');
  117. attr := doc.CreateAttributeNS('http://www.freepascal.org', 'fpc:newAttr');
  118. el.SetAttributeNodeNS(attr);
  119. AssertEquals('ownerElement_before', el, attr.OwnerElement);
  120. el.RemoveAttributeNode(attr);
  121. AssertNull('ownerElement_after', attr.ownerElement);
  122. end;
  123. // verify that replacing a node by itself does not remove it from the tree
  124. // (specs say this is implementation-dependent, but guess that means either
  125. // no-op or raising an exception, not removal).
  126. procedure TDOMTestExtra.replacesamechild;
  127. var
  128. doc: TDOMDocument;
  129. root, el, prev, next: TDOMNode;
  130. begin
  131. LoadStringData(doc, '<root><child1/><child2/><child3/></root>');
  132. root := doc.DocumentElement;
  133. el := root.ChildNodes[1];
  134. prev := el.PreviousSibling;
  135. next := el.NextSibling;
  136. AssertEquals('prev_name_before', 'child1', prev.NodeName);
  137. AssertEquals('next_name_before', 'child3', next.NodeName);
  138. root.replaceChild(el, el);
  139. prev := el.PreviousSibling;
  140. next := el.NextSibling;
  141. AssertNotNull('prev_after', prev);
  142. AssertNotNull('prev_after', next);
  143. AssertEquals('prev_name_after', 'child1', prev.NodeName);
  144. AssertEquals('next_name_after', 'child3', next.NodeName);
  145. end;
  146. const
  147. nsURI1 = 'http://www.example.com/ns1';
  148. nsURI2 = 'http://www.example.com/ns2';
  149. // verify the namespace fixup with two nested elements
  150. // (same localName, different nsURI, and no prefixes)
  151. procedure TDOMTestExtra.nsFixup1;
  152. var
  153. domImpl: TDOMImplementation;
  154. origDoc: TDOMDocument;
  155. parsedDoc: TDOMDocument;
  156. docElem: TDOMElement;
  157. el: TDOMElement;
  158. stream: TStringStream;
  159. list: TDOMNodeList;
  160. begin
  161. FParser.Options.Namespaces := True;
  162. domImpl := GetImplementation;
  163. origDoc := domImpl.createDocument(nsURI1, 'test', nil);
  164. GC(origDoc);
  165. docElem := origDoc.documentElement;
  166. el := origDoc.CreateElementNS(nsURI2, 'test');
  167. docElem.AppendChild(el);
  168. stream := TStringStream.Create('');
  169. GC(stream);
  170. writeXML(origDoc, stream);
  171. LoadStringData(parsedDoc, stream.DataString);
  172. docElem := parsedDoc.documentElement;
  173. assertEquals('docElemLocalName', 'test', docElem.localName);
  174. assertEquals('docElemNS', nsURI1, docElem.namespaceURI);
  175. list := docElem.GetElementsByTagNameNS(nsURI2, '*');
  176. assertEquals('ns2_elementCount', 1, list.Length);
  177. el := TDOMElement(list[0]);
  178. assertEquals('ns2_nodeName', 'test', el.nodeName);
  179. end;
  180. // verify the namespace fixup with two nested elements
  181. // (same localName, different nsURI, different prefixes)
  182. procedure TDOMTestExtra.nsFixup2;
  183. var
  184. domImpl: TDOMImplementation;
  185. origDoc: TDOMDocument;
  186. parsedDoc: TDOMDocument;
  187. docElem: TDOMElement;
  188. el: TDOMElement;
  189. stream: TStringStream;
  190. list: TDOMNodeList;
  191. begin
  192. FParser.Options.Namespaces := True;
  193. domImpl := GetImplementation;
  194. origDoc := domImpl.createDocument(nsURI1, 'a:test', nil);
  195. GC(origDoc);
  196. docElem := origDoc.documentElement;
  197. el := origDoc.CreateElementNS(nsURI2, 'b:test');
  198. docElem.AppendChild(el);
  199. stream := TStringStream.Create('');
  200. GC(stream);
  201. writeXML(origDoc, stream);
  202. LoadStringData(parsedDoc, stream.DataString);
  203. docElem := parsedDoc.documentElement;
  204. assertEquals('docElemLocalName', 'test', docElem.localName);
  205. assertEquals('docElemNS', nsURI1, docElem.namespaceURI);
  206. list := docElem.GetElementsByTagNameNS(nsURI2, '*');
  207. assertEquals('ns2_elementCount', 1, list.Length);
  208. el := TDOMElement(list[0]);
  209. assertEquals('ns2_nodeName', 'b:test', el.nodeName);
  210. end;
  211. // verify the namespace fixup with two nested elements and an attribute
  212. // attribute's prefix must change to that of document element
  213. procedure TDOMTestExtra.nsFixup3;
  214. var
  215. domImpl: TDOMImplementation;
  216. origDoc: TDOMDocument;
  217. parsedDoc: TDOMDocument;
  218. docElem: TDOMElement;
  219. el: TDOMElement;
  220. stream: TStringStream;
  221. list: TDOMNodeList;
  222. attr: TDOMAttr;
  223. begin
  224. FParser.Options.Namespaces := True;
  225. domImpl := GetImplementation;
  226. origDoc := domImpl.createDocument(nsURI1, 'a:test', nil);
  227. GC(origDoc);
  228. docElem := origDoc.documentElement;
  229. el := origDoc.CreateElementNS(nsURI2, 'b:test');
  230. docElem.AppendChild(el);
  231. el.SetAttributeNS(nsURI1, 'test:attr', 'test value');
  232. stream := TStringStream.Create('');
  233. GC(stream);
  234. writeXML(origDoc, stream);
  235. LoadStringData(parsedDoc, stream.DataString);
  236. docElem := parsedDoc.documentElement;
  237. assertEquals('docElemLocalName', 'test', docElem.localName);
  238. assertEquals('docElemNS', nsURI1, docElem.namespaceURI);
  239. list := docElem.GetElementsByTagNameNS(nsURI2, '*');
  240. assertEquals('ns2_elementCount', 1, list.Length);
  241. el := TDOMElement(list[0]);
  242. attr := el.GetAttributeNodeNS(nsURI1, 'attr');
  243. assertEquals('attr_nodeName', 'a:attr', attr.nodeName);
  244. end;
  245. initialization
  246. RegisterTest(TDOMTestExtra);
  247. end.