Version 1
[yaffs-website] / node_modules / min-document / test / test-document.js
1 var test = require("tape")
2
3 module.exports = testDocument
4
5 function testDocument(document) {
6     var cleanup = require('./cleanup')(document)
7     var Event = require('../event');
8
9     test("document is a Document", function (assert) {
10         assert.equal(typeof document.createTextNode, "function")
11         assert.equal(typeof document.createElement, "function")
12         assert.equal(typeof document.createDocumentFragment, "function")
13
14         assert.end()
15     })
16
17     test("document has a head property", function(assert) {
18         assert.equal(document.head.tagName, "HEAD")
19         assert.end()
20     })
21
22     test("document has nodeType 9", function (assert) {
23         assert.equal(document.nodeType, 9)
24         assert.end()
25     })
26
27     test("can do stuff", function (assert) {
28         var div = document.createElement("div")
29         div.className = "foo bar"
30
31         var span = document.createElement("span")
32         div.appendChild(span)
33         span.textContent = "Hello! <&>"
34
35         var html = String(div.outerHTML || div)
36
37         assert.equal(html, "<div class=\"foo bar\">" +
38             "<span>Hello! &lt;&amp;&gt;</span></div>")
39
40         cleanup()
41         assert.end()
42     })
43
44     test("can createDocumentFragment", function (assert) {
45         var frag = document.createDocumentFragment()
46
47         assert.equal(frag.nodeType, 11)
48
49         var h1 = document.createElement("h1")
50         var h2 = document.createElement("h2")
51
52         assert.equal(h1.nodeType, 1)
53         assert.equal(h1.nodeType, 1)
54
55         frag.appendChild(h1)
56         assert.equal(fragString(frag), "<h1></h1>")
57
58         frag.appendChild(h2)
59         assert.equal(fragString(frag), "<h1></h1><h2></h2>")
60
61         frag.removeChild(h1)
62         assert.equal(fragString(frag), "<h2></h2>")
63
64         frag.replaceChild(h1, h2)
65         assert.equal(fragString(frag), "<h1></h1>")
66
67         cleanup()
68         assert.end()
69     })
70
71     test("can getElementById", function (assert) {
72
73         function append_div(id, parent) {
74             var div = document.createElement("div")
75             div.id = id
76             parent.appendChild(div)
77             return div
78         }
79
80         var div1   = append_div(1, document.body)
81         var div2   = append_div(2, document.body)
82         var div3   = append_div(3, document.body)
83
84         var div11  = append_div(11, div1)
85         var div12  = append_div(12, div1)
86         var div21  = append_div(21, div2)
87         var div22  = append_div(22, div2)
88         var div221 = append_div(221, div22)
89         var div222 = append_div(222, div22)
90
91         assert.equal(document.getElementById(1),    div1)
92         assert.equal(document.getElementById("2"),  div2)
93         assert.equal(document.getElementById(3),    div3)
94         assert.equal(document.getElementById(11),   div11)
95         assert.equal(document.getElementById(12),   div12)
96         assert.equal(document.getElementById(21),   div21)
97         assert.equal(document.getElementById(22),   div22)
98         assert.equal(document.getElementById(221),  div221)
99         assert.equal(document.getElementById(222),  div222)
100
101         cleanup()
102         assert.end()
103     })
104
105     test("can getElementsByClassName for a single class", function(assert) {
106         function append_div(className, parent) {
107             var div = document.createElement("div")
108             div.className = className
109             parent.appendChild(div)
110             return div
111         }
112
113         function assertSingleMatch(className, expectedElement) {
114             var result = document.getElementsByClassName(className)
115             assert.equal(result.length, 1)
116             assert.equal(result[0], expectedElement)
117         }
118
119         var divA   = append_div("A", document.body)
120         var divB   = append_div("B", document.body)
121         var divC   = append_div("C", document.body)
122
123         var divA1  = append_div("A1",  divA)
124         var divA2  = append_div("A2",  divA)
125         var divB1  = append_div("B1",  divB)
126         var divB2  = append_div("B2",  divB)
127         var divB2a = append_div("B2a", divB2)
128         var divB2b = append_div("B2b", divB2)
129
130         assertSingleMatch("A",    divA)
131         assertSingleMatch("B",    divB)
132         assertSingleMatch("C",    divC)
133         assertSingleMatch("A1",   divA1)
134         assertSingleMatch("A2",   divA2)
135         assertSingleMatch("B1",   divB1)
136         assertSingleMatch("B2",   divB2)
137         assertSingleMatch("B2a",  divB2a)
138         assertSingleMatch("B2b",  divB2b)
139
140         cleanup()
141         assert.end()
142     })
143
144     test("can getElementsByClassName for many elements", function (assert) {
145         function h(className) {
146             var div = document.createElement("div")
147             div.className = className
148             return div
149         }
150
151         document.body.appendChild(h("multi-class-bar"))
152         document.body.appendChild(h("multi-class-bar"))
153
154         var elems = document.getElementsByClassName("multi-class-bar")
155         assert.equal(elems.length, 2)
156
157         cleanup()
158         assert.end()
159     })
160
161     test("can getElementsByClassName for many classes", function(assert) {
162         function append_div(classNames, parent) {
163             var div = document.createElement("div")
164             div.className = classNames
165             parent.appendChild(div)
166             return div
167         }
168
169         function assertMatch(classNames, expectedElements) {
170             var result = document.getElementsByClassName(classNames)
171             assert.equal(result.length, expectedElements.length)
172             for (var i = 0; i < expectedElements.length; i++) {
173                 assert.notEqual(expectedElements.indexOf(result[i]), -1)
174             }
175         }
176
177         var divXYZ   = append_div("X Y Z", document.body)
178         var divYZ   = append_div("Y Z", document.body)
179         var divZX  = append_div("Z X", document.body)
180
181         var divX1X2  = append_div("X1 X2",  divXYZ)
182         var divX1X2Y1  = append_div("X1 X2 Y1",  divXYZ)
183
184
185         assertMatch("X",    [divXYZ, divZX])
186         assertMatch("Y Z",    [divXYZ, divYZ])
187         assertMatch("X Y Z",    [divXYZ])
188         assertMatch("X1 X2",   [divX1X2, divX1X2Y1])
189
190         cleanup()
191         assert.end()
192     })
193
194     test("can create/manipulate textnodes", function (assert) {
195         var textnode = document.createTextNode("hello")
196
197         assert.equal(textnode.nodeType, 3)
198         assert.equal(textnode.data, "hello")
199         assert.equal(typeof textnode.replaceData, "function")
200
201         textnode.replaceData(0, 7, "nightly")
202         assert.equal(textnode.nodeType, 3)
203         assert.equal(textnode.data, "nightly")
204         assert.equal(typeof textnode.replaceData, "function")
205
206         textnode.replaceData(1, 1, "ou")
207         assert.equal(textnode.nodeType, 3)
208         assert.equal(textnode.data, "noughtly")
209
210         assert.end()
211     })
212
213     test("owner document is set", function (assert) {
214         var textnode = document.createTextNode("hello")
215         var domnode = document.createElement("div")
216         var fragment = document.createDocumentFragment()
217
218         assert.equal(textnode.ownerDocument, document)
219         assert.equal(domnode.ownerDocument, document)
220         assert.equal(fragment.ownerDocument, document)
221
222         assert.end()
223     })
224
225     test("Create namespaced nodes", function (assert) {
226         var svgURI = "http://www.w3.org/2000/svg"
227         var htmlURI = "http://www.w3.org/1999/xhtml"
228
229         var noNS = document.createElement("div")
230         var svgNS = document.createElementNS(svgURI, "svg")
231         var emptyNS = document.createElementNS("", "div")
232         var nullNS = document.createElementNS(null, "div")
233         var undefNS = document.createElementNS(undefined, "div")
234         var caseNS = document.createElementNS("Oops", "AbC")
235         var htmlNS = document.createElement("div")
236
237         assert.equal(noNS.tagName, "DIV")
238         assert.equal(noNS.namespaceURI, htmlURI)
239         assert.equal(elemString(noNS), "<div></div>")
240
241         assert.equal(svgNS.tagName, "svg")
242         assert.equal(svgNS.namespaceURI, svgURI)
243         assert.equal(elemString(svgNS), "<svg></svg>")
244
245         assert.equal(emptyNS.tagName, "div")
246         assert.equal(emptyNS.namespaceURI, null)
247         assert.equal(elemString(emptyNS), "<div></div>")
248
249         assert.equal(nullNS.tagName, "div")
250         assert.equal(nullNS.namespaceURI, null)
251         assert.equal(elemString(nullNS), "<div></div>")
252
253         assert.equal(undefNS.tagName, "div")
254         assert.equal(undefNS.namespaceURI, "undefined")
255         assert.equal(elemString(undefNS), "<div></div>")
256
257         assert.equal(caseNS.tagName, "AbC")
258         assert.equal(caseNS.namespaceURI, "Oops")
259         assert.equal(elemString(caseNS), "<AbC></AbC>")
260
261         assert.equal(htmlNS.tagName, "DIV")
262         assert.equal(htmlNS.namespaceURI, htmlURI)
263         assert.equal(elemString(htmlNS), "<div></div>")
264
265         assert.end()
266     })
267
268     test("Can insert before", function (assert) {
269         var rootNode = document.createElement("div")
270         var child = document.createElement("div")
271         var newElement = document.createElement("div")
272         rootNode.appendChild(child)
273         var el = rootNode.insertBefore(newElement, child)
274         assert.equal(el, newElement)
275         assert.equal(rootNode.childNodes.length, 2)
276         assert.equal(rootNode.childNodes[0], newElement)
277         assert.equal(rootNode.childNodes[1], child)
278         cleanup()
279         assert.end()
280     })
281
282     test("Insert before null appends to end", function (assert) {
283         var rootNode = document.createElement("div")
284         var child = document.createElement("div")
285         var newElement = document.createElement("div")
286         rootNode.appendChild(child)
287         var el = rootNode.insertBefore(newElement, null)
288         assert.equal(el, newElement)
289         assert.equal(rootNode.childNodes.length, 2)
290         assert.equal(rootNode.childNodes[0], child)
291         assert.equal(rootNode.childNodes[1], newElement)
292         cleanup()
293         assert.end()
294     })
295
296     test("Node insertions remove node from parent", function (assert) {
297         var parent = document.createElement("div")
298         var c1 = document.createElement("div")
299         var c2 = document.createElement("div")
300         var c3 = document.createElement("div")
301         parent.appendChild(c1)
302         parent.appendChild(c2)
303         parent.appendChild(c3)
304
305         var rootNode = document.createElement("div")
306
307         var node1 = rootNode.appendChild(c1)
308         assert.equal(node1, c1)
309         assert.equal(parent.childNodes.length, 2)
310         assert.equal(c1.parentNode, rootNode)
311
312         var node2 = rootNode.insertBefore(c2, c1)
313         assert.equal(node2, c2)
314         assert.equal(parent.childNodes.length, 1)
315         assert.equal(c2.parentNode, rootNode)
316
317         var node3 = rootNode.replaceChild(c3, c2)
318         assert.equal(node3, c2)
319         assert.equal(parent.childNodes.length, 0)
320         assert.equal(c3.parentNode, rootNode)
321         assert.equal(c2.parentNode, null)
322
323         cleanup()
324         assert.end()
325     })
326
327     test("input has type=text by default", function (assert) {
328         var elem = document.createElement("input")
329         assert.equal(elem.getAttribute("type"), "text");
330         assert.equal(elemString(elem), "<input type=\"text\" />")
331         assert.end()
332     })
333
334     test("input type=text can be overridden", function (assert) {
335         var elem = document.createElement("input")
336         elem.setAttribute("type", "hidden")
337         assert.equal(elem.getAttribute("type"), "hidden");
338         assert.equal(elemString(elem), "<input type=\"hidden\" />")
339         assert.end()
340     })
341
342     test("can set and get attributes", function (assert) {
343         var elem = document.createElement("div")
344         assert.equal(elem.getAttribute("foo"), null)
345         assert.equal(elemString(elem), "<div></div>")
346         assert.notOk(elem.hasAttribute('foo'))
347
348         elem.setAttribute("foo", "bar")
349         assert.equal(elem.getAttribute("foo"), "bar")
350         assert.equal(elemString(elem), "<div foo=\"bar\"></div>")
351         assert.ok(elem.hasAttribute('foo'))
352
353         elem.removeAttribute("foo")
354         assert.equal(elem.getAttribute("foo"), null)
355         assert.equal(elemString(elem), "<div></div>")
356         assert.notOk(elem.hasAttribute('foo'))
357
358         assert.end()
359     })
360
361     test("can set and set style properties", function(assert) {
362       var elem = document.createElement("div")
363       assert.equal(elemString(elem), "<div></div>")
364
365       elem.style.color = "red";
366       assert.equal(elem.style.color, "red")
367       assert.equal(elemString(elem), "<div style=\"color:red;\"></div>")
368
369       elem.style.background = "blue";
370       assert.equal(elem.style.color, "red")
371       assert.equal(elem.style.background, "blue")
372       assert.equal(elemString(elem),
373                    "<div style=\"color:red;background:blue;\"></div>")
374
375       assert.end()
376     })
377
378     test("can set and get namespaced attributes", function(assert) {
379         var elem = document.createElement("div")
380
381         var ns = "http://ns.com/my"
382         assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
383         elem.setAttributeNS(ns, "myns:myattr", "the value")
384         assert.equal(elem.getAttributeNS(ns, "myattr"), "the value")
385         assert.equal(elemString(elem), '<div myns:myattr="the value"></div>')
386         elem.removeAttributeNS(ns, "myattr")
387         assert.equal(elem.getAttributeNS(ns, "myattr"), blankAttributeNS())
388
389         // Should work much like get/setAttribute when namespace is null.
390         assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
391         assert.equal(elem.getAttribute("foo"), null)
392         elem.setAttributeNS(null, "foo", "bar")
393         assert.equal(elem.getAttributeNS(null, "foo"), "bar")
394         assert.equal(elem.getAttribute("foo"), "bar")
395         elem.removeAttributeNS(null, "foo")
396         assert.equal(elem.getAttributeNS(null, "foo"), blankAttributeNS())
397         assert.equal(elem.getAttribute("foo"), null)
398         assert.end()
399     })
400
401     test("can getElementsByTagName", function(assert) {
402         var parent = document.createElement("div")
403         var child1 = document.createElement("span")
404         var child2 = document.createElement("span")
405
406         child1.id = "foo"
407         child2.id = "bar"
408
409         child1.appendChild(child2)
410         parent.appendChild(child1)
411         document.body.appendChild(parent)
412
413         var elems = document.getElementsByTagName("SPAN")
414
415         assert.equal(elems.length, 2)
416         assert.equal(elems[0].id, "foo")
417         assert.equal(elems[1].id, "bar")
418
419         cleanup()
420         assert.end()
421     })
422
423     test("can getElementsByTagName with *", function(assert) {
424         document.body.appendChild(document.createElement("div"))
425
426         var elems = document.getElementsByTagName("*")
427
428         assert.equal(elems.length, 4)
429         assert.equal(elems[0].tagName, "HTML")
430         assert.equal(elems[1].tagName, "HEAD")
431         assert.equal(elems[2].tagName, "BODY")
432         assert.equal(elems[3].tagName, "DIV")
433
434         cleanup()
435         assert.end()
436     })
437
438     test("getElement* methods search outside the body", function(assert) {
439         var html = document.documentElement;
440         assert.equal(document.getElementsByTagName("html")[0], html)
441
442         html.id = "foo"
443         assert.equal(document.getElementById("foo"), html)
444
445         html.className = "bar"
446         assert.equal(document.getElementsByClassName("bar")[0], html)
447
448         // cleanup
449         html.id = ""
450         html.className = ""
451
452         cleanup()
453         assert.end()
454     })
455
456     test("getElement* methods can be passed to map()", function(assert) {
457         var e1 = document.createElement("div")
458         var e2 = document.createElement("span")
459
460         document.body.appendChild(e1)
461         document.body.appendChild(e2)
462
463         assert.deepEqual(
464             ["div", "span"].map(document.getElementsByTagName.bind(document)),
465             [[e1], [e2]]
466         )
467
468         e1.id = "1"
469         e2.id = "2"
470
471         assert.deepEqual(
472             ["1", "2"].map(document.getElementById.bind(document)),
473             [e1, e2]
474         )
475
476         e1.className = "foo"
477         e2.className = "bar"
478
479         assert.deepEqual(
480             ["foo", "bar"].map(document.getElementsByClassName.bind(document)),
481             [[e1], [e2]]
482         )
483
484         cleanup()
485         assert.end()
486     })
487
488     test("can check if it contains an element", function(assert) {
489         var el = document.createElement("div")
490         document.body.appendChild(el)
491
492         assert.equals(document.contains(document.body), true)
493         assert.equals(document.contains(el), true)
494
495         cleanup()
496         assert.end()
497     })
498
499     test("can do events", function (assert) {
500         var x = 1
501         function incx() { x++ }
502
503         var ev = new Event();
504         ev.initEvent("click");
505         document.addEventListener("click", incx)
506         document.dispatchEvent(ev)
507
508         assert.equal(x, 2)
509
510         document.removeEventListener("click", incx)
511         document.dispatchEvent(ev)
512
513         assert.equal(x, 2)
514         assert.end()
515     })
516
517     function blankAttributeNS() {
518         // Most browsers conform to the latest version of the DOM spec,
519         // which requires `getAttributeNS` to return `null` when the attribute
520         // doesn't exist, but some browsers (including phantomjs) implement the
521         // old version of the spec and return an empty string instead, see:
522         // https://developer.mozilla.org/en-US/docs/Web/API/element.getAttributeNS#Return_value
523         var div = document.createElement("div")
524         var blank = div.getAttributeNS(null, "foo")
525         if (!(blank === null || blank === "")) {
526             throw "Expected blank attribute to be either null or empty string"
527         }
528         return blank;
529     }
530
531     function elemString(element) {
532         var html = String(element) || "[]"
533
534         if (html.charAt(0) === "[") {
535             html = element.outerHTML
536             if (!html && !element.parentNode) {
537                 var div = document.createElement("div")
538                 div.appendChild(element)
539                 html = div.innerHTML
540                 div.removeChild(element)
541             }
542         }
543
544         return html
545     }
546
547     function fragString(fragment) {
548         var html = String(fragment)
549
550
551         if (html === "[object DocumentFragment]") {
552             var innerHTML = []
553             for (var i = 0; i < fragment.childNodes.length; i++) {
554                 var node = fragment.childNodes[i]
555                 innerHTML.push(String(node.outerHTML || node))
556             }
557             html = innerHTML.join("")
558         }
559
560         return html
561     }
562 }
563
564