test_isequalnode.js (11445B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // TEST CODE 7 8 var doc; // cache for use in all tests 9 10 add_setup(function init() { 11 doc = ParseFile("isequalnode_data.xml"); 12 }); 13 14 add_task(function test_isEqualNode_setAttribute() { 15 // NOTE: 0, 2 are whitespace 16 var test1 = doc.getElementById("test_setAttribute"); 17 var node1 = test1.childNodes.item(1); 18 var node2 = test1.childNodes.item(3); 19 20 check_eq_nodes(node1, node2); 21 22 node1.setAttribute("bar", "baz"); 23 check_neq_nodes(node1, node2); 24 25 node2.setAttribute("bar", "baz"); 26 check_eq_nodes(node1, node2); 27 28 // the null namespace is equivalent to no namespace -- section 1.3.3 29 // (XML Namespaces) of DOM 3 Core 30 node1.setAttributeNS(null, "quux", "17"); 31 check_neq_nodes(node1, node2); 32 33 node2.setAttribute("quux", "17"); 34 check_eq_nodes(node1, node2); 35 36 node2.setAttributeNS("http://mozilla.org/", "seamonkey", "rheet"); 37 check_neq_nodes(node1, node2); 38 39 node1.setAttribute("seamonkey", "rheet"); 40 check_neq_nodes(node1, node2); 41 42 node1.setAttributeNS("http://mozilla.org/", "seamonkey", "rheet"); 43 check_neq_nodes(node1, node2); 44 45 // this overwrites the namespaced "seamonkey" attribute added to node2 46 // earlier, because this simply sets whatever attribute has the fully 47 // qualified name "seamonkey" (the setAttributeNS attribute string wasn't 48 // prefixed) -- consequently, node1 and node2 are still unequal 49 node2.setAttribute("seamonkey", "rheet"); 50 check_neq_nodes(node1, node2); 51 }); 52 53 add_task(function test_isEqualNode_clones() { 54 // tests all elements and attributes in the document 55 var all_elts = doc.getElementsByTagName("*"); 56 for (var i = 0; i < all_elts.length; i++) { 57 var elt = all_elts.item(i); 58 check_eq_nodes(elt, elt.cloneNode(true)); 59 60 var attrs = elt.attributes; 61 for (var j = 0; j < attrs.length; j++) { 62 var attr = attrs.item(j); 63 check_eq_nodes(attr, attr.cloneNode(true)); 64 } 65 } 66 67 var elm = doc.createElement("foo"); 68 check_eq_nodes(elm, elm.cloneNode(true)); 69 check_eq_nodes(elm, elm.cloneNode(false)); 70 71 elm.setAttribute("fiz", "eit"); 72 check_eq_nodes(elm, elm.cloneNode(true)); 73 check_eq_nodes(elm, elm.cloneNode(false)); 74 75 elm.setAttributeNS("http://example.com/", "trendoid", "arthroscope"); 76 check_eq_nodes(elm, elm.cloneNode(true)); 77 check_eq_nodes(elm, elm.cloneNode(false)); 78 79 var elm2 = elm.cloneNode(true); 80 check_eq_nodes(elm, elm2); 81 82 const TEXT = "fetishist"; 83 84 elm.textContent = TEXT; 85 check_neq_nodes(elm, elm2); 86 87 check_neq_nodes(elm, elm.cloneNode(false)); 88 check_eq_nodes(elm, elm.cloneNode(true)); 89 90 elm2.appendChild(doc.createTextNode(TEXT)); 91 check_eq_nodes(elm, elm2); 92 93 var att = doc.createAttribute("bar"); 94 check_eq_nodes(att, att.cloneNode(true)); 95 check_eq_nodes(att, att.cloneNode(false)); 96 }); 97 98 add_task(function test_isEqualNode_variety() { 99 const nodes = [ 100 doc.createElement("foo"), 101 doc.createElementNS("http://example.com/", "foo"), 102 doc.createElementNS("http://example.org/", "foo"), 103 doc.createElementNS("http://example.com/", "FOO"), 104 doc.createAttribute("foo", "href='biz'"), 105 doc.createAttributeNS("http://example.com/", "foo", "href='biz'"), 106 doc.createTextNode("foo"), 107 doc.createTextNode(" "), 108 doc.createTextNode(" "), 109 doc.createComment("foo"), 110 doc.createProcessingInstruction("foo", "href='biz'"), 111 doc.implementation.createDocumentType("foo", "href='biz'", ""), 112 doc.implementation.createDocument("http://example.com/", "foo", null), 113 doc.createDocumentFragment(), 114 ]; 115 116 for (var i = 0; i < nodes.length; i++) { 117 for (var j = i; j < nodes.length; j++) { 118 if (i == j) { 119 check_eq_nodes(nodes[i], nodes[j]); 120 } else { 121 check_neq_nodes(nodes[i], nodes[j]); 122 } 123 } 124 } 125 }); 126 127 add_task(function test_isEqualNode_normalization() { 128 var norm = doc.getElementById("test_normalization"); 129 var node1 = norm.childNodes.item(1); 130 var node2 = norm.childNodes.item(3); 131 132 check_eq_nodes(node1, node2); 133 134 node1.appendChild(doc.createTextNode("")); 135 check_neq_nodes(node1, node2); 136 137 node1.normalize(); 138 check_eq_nodes(node1, node2); 139 140 node2.appendChild(doc.createTextNode("fun")); 141 node2.appendChild(doc.createTextNode("ctor")); 142 node1.appendChild(doc.createTextNode("functor")); 143 check_neq_nodes(node1, node2); 144 145 node1.normalize(); 146 check_neq_nodes(node1, node2); 147 148 node2.normalize(); 149 check_eq_nodes(node1, node2); 150 151 // reset 152 while (node1.hasChildNodes()) { 153 node1.removeChild(node1.childNodes.item(0)); 154 } 155 while (node2.hasChildNodes()) { 156 node2.removeChild(node2.childNodes.item(0)); 157 } 158 159 // attribute normalization testing 160 161 var at1 = doc.createAttribute("foo"); 162 var at2 = doc.createAttribute("foo"); 163 check_eq_nodes(at1, at2); 164 165 // Attr.appendChild isn't implemented yet (bug 56758), so don't run this yet 166 if (false) { 167 at1.appendChild(doc.createTextNode("rasp")); 168 at2.appendChild(doc.createTextNode("rasp")); 169 check_eq_nodes(at1, at2); 170 171 at1.appendChild(doc.createTextNode("")); 172 check_neq_nodes(at1, at2); 173 174 at1.normalize(); 175 check_eq_nodes(at1, at2); 176 177 at1.appendChild(doc.createTextNode("berry")); 178 check_neq_nodes(at1, at2); 179 180 at2.appendChild(doc.createTextNode("ber")); 181 check_neq_nodes(at1, at2); 182 183 at2.appendChild(doc.createTextNode("ry")); 184 check_neq_nodes(at1, at2); 185 186 at1.normalize(); 187 check_neq_nodes(at1, at2); 188 189 at2.normalize(); 190 check_eq_nodes(at1, at2); 191 } 192 193 node1.setAttributeNode(at1); 194 check_neq_nodes(node1, node2); 195 196 node2.setAttributeNode(at2); 197 check_eq_nodes(node1, node2); 198 199 var n1text1 = doc.createTextNode("ratfink"); 200 var n1elt = doc.createElement("fruitcake"); 201 var n1text2 = doc.createTextNode("hydrospanner"); 202 203 node1.appendChild(n1text1); 204 node1.appendChild(n1elt); 205 node1.appendChild(n1text2); 206 207 check_neq_nodes(node1, node2); 208 209 var n2text1a = doc.createTextNode("rat"); 210 var n2text1b = doc.createTextNode("fink"); 211 var n2elt = doc.createElement("fruitcake"); 212 var n2text2 = doc.createTextNode("hydrospanner"); 213 214 node2.appendChild(n2text1b); 215 node2.appendChild(n2elt); 216 node2.appendChild(n2text2); 217 check_neq_nodes(node1, node2); 218 219 node2.insertBefore(n2text1a, n2text1b); 220 check_neq_nodes(node1, node2); 221 222 var tmp_node1 = node1.cloneNode(true); 223 tmp_node1.normalize(); 224 var tmp_node2 = node2.cloneNode(true); 225 tmp_node2.normalize(); 226 check_eq_nodes(tmp_node1, tmp_node2); 227 228 n2elt.appendChild(doc.createTextNode("")); 229 check_neq_nodes(node1, node2); 230 231 tmp_node1 = node1.cloneNode(true); 232 tmp_node1.normalize(); 233 tmp_node2 = node2.cloneNode(true); 234 tmp_node2.normalize(); 235 check_eq_nodes(tmp_node1, tmp_node2); 236 237 var typeText1 = doc.createTextNode("type"); 238 n2elt.appendChild(typeText1); 239 tmp_node1 = node1.cloneNode(true); 240 tmp_node1.normalize(); 241 tmp_node2 = node2.cloneNode(true); 242 tmp_node2.normalize(); 243 check_neq_nodes(tmp_node1, tmp_node2); 244 245 n1elt.appendChild(doc.createTextNode("typedef")); 246 tmp_node1 = node1.cloneNode(true); 247 tmp_node1.normalize(); 248 tmp_node2 = node2.cloneNode(true); 249 tmp_node2.normalize(); 250 check_neq_nodes(tmp_node1, tmp_node2); 251 check_neq_nodes(n1elt, n2elt); 252 253 var typeText2 = doc.createTextNode("def"); 254 n2elt.appendChild(typeText2); 255 tmp_node1 = node1.cloneNode(true); 256 tmp_node1.normalize(); 257 tmp_node2 = node2.cloneNode(true); 258 tmp_node2.normalize(); 259 check_eq_nodes(tmp_node1, tmp_node2); 260 check_neq_nodes(node1, node2); 261 262 n2elt.insertBefore(doc.createTextNode(""), typeText2); 263 check_neq_nodes(node1, node2); 264 265 n2elt.insertBefore(doc.createTextNode(""), typeText2); 266 check_neq_nodes(node1, node2); 267 268 n2elt.insertBefore(doc.createTextNode(""), typeText1); 269 check_neq_nodes(node1, node2); 270 271 node1.normalize(); 272 node2.normalize(); 273 check_eq_nodes(node1, node2); 274 }); 275 276 add_task(function test_isEqualNode_whitespace() { 277 equality_check_kids("test_pi1", true); 278 equality_check_kids("test_pi2", true); 279 equality_check_kids("test_pi3", false); 280 equality_check_kids("test_pi4", true); 281 equality_check_kids("test_pi5", true); 282 283 equality_check_kids("test_elt1", false); 284 equality_check_kids("test_elt2", false); 285 equality_check_kids("test_elt3", true); 286 equality_check_kids("test_elt4", false); 287 equality_check_kids("test_elt5", false); 288 289 equality_check_kids("test_comment1", true); 290 equality_check_kids("test_comment2", false); 291 equality_check_kids("test_comment3", false); 292 equality_check_kids("test_comment4", true); 293 294 equality_check_kids("test_text1", true); 295 equality_check_kids("test_text2", false); 296 equality_check_kids("test_text3", false); 297 298 equality_check_kids("test_cdata1", false); 299 equality_check_kids("test_cdata2", true); 300 equality_check_kids("test_cdata3", false); 301 equality_check_kids("test_cdata4", false); 302 equality_check_kids("test_cdata5", false); 303 }); 304 305 add_task(function test_isEqualNode_namespaces() { 306 equality_check_kids("test_ns1", false); 307 equality_check_kids("test_ns2", false); 308 309 // XXX want more tests here! 310 }); 311 312 // XXX This test is skipped: 313 // should Node.isEqualNode(null) throw or return false? 314 add_task(function test_isEqualNode_null() { 315 check_neq_nodes(doc, null); 316 317 var elts = doc.getElementsByTagName("*"); 318 for (var i = 0; i < elts.length; i++) { 319 var elt = elts.item(i); 320 check_neq_nodes(elt, null); 321 322 var attrs = elt.attributes; 323 for (var j = 0; j < attrs.length; j++) { 324 var att = attrs.item(j); 325 check_neq_nodes(att, null); 326 327 for (var k = 0; k < att.childNodes.length; k++) { 328 check_neq_nodes(att.childNodes.item(k), null); 329 } 330 } 331 } 332 }).skip(); 333 334 add_task(function test_isEqualNode_wholeDoc() { 335 doc = ParseFile("isequalnode_data.xml"); 336 var doc2 = ParseFile("isequalnode_data.xml"); 337 var tw1 = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null); 338 var tw2 = doc2.createTreeWalker(doc2, NodeFilter.SHOW_ALL, null); 339 do { 340 check_eq_nodes(tw1.currentNode, tw2.currentNode); 341 tw1.nextNode(); 342 } while (tw2.nextNode()); 343 }); 344 345 // TESTING FUNCTIONS 346 347 /** 348 * Compares the first and third (zero-indexed) child nodes of the element 349 * (typically to allow whitespace) referenced by parentId for isEqualNode 350 * equality or inequality based on the value of areEqual. 351 * 352 * Note that this means that the contents of the element referenced by parentId 353 * are whitespace-sensitive, and a stray space introduced during an edit to the 354 * file could result in a correct but unexpected (in)equality failure. 355 */ 356 function equality_check_kids(parentId, areEqual) { 357 var parent = doc.getElementById(parentId); 358 var kid1 = parent.childNodes.item(1); 359 var kid2 = parent.childNodes.item(3); 360 361 if (areEqual) { 362 check_eq_nodes(kid1, kid2); 363 } else { 364 check_neq_nodes(kid1, kid2); 365 } 366 } 367 368 function check_eq_nodes(n1, n2) { 369 if (n1 && !n1.isEqualNode(n2)) { 370 do_throw(n1 + " should be equal to " + n2); 371 } 372 if (n2 && !n2.isEqualNode(n1)) { 373 do_throw(n2 + " should be equal to " + n1); 374 } 375 if (!n1 && !n2) { 376 do_throw("nodes both null!"); 377 } 378 } 379 380 function check_neq_nodes(n1, n2) { 381 if (n1 && n1.isEqualNode(n2)) { 382 do_throw(n1 + " should not be equal to " + n2); 383 } 384 if (n2 && n2.isEqualNode(n1)) { 385 do_throw(n2 + " should not be equal to " + n1); 386 } 387 if (!n1 && !n2) { 388 do_throw("n1 and n2 both null!"); 389 } 390 }