| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #library('DocumentFragmentTest'); | |
| 6 #import('../../../../lib/unittest/unittest.dart'); | |
| 7 #import('../../../../lib/unittest/html_config.dart'); | |
| 8 #import('dart:html'); | |
| 9 #source('util.dart'); | |
| 10 | |
| 11 main() { | |
| 12 useHtmlConfiguration(); | |
| 13 | |
| 14 Collection<String> _nodeStrings(Collection<Node> input) { | |
| 15 var out = new List<String>(); | |
| 16 for (Node n in input) { | |
| 17 if (n is Element) { | |
| 18 Element e = n; | |
| 19 out.add(e.tagName); | |
| 20 } else { | |
| 21 out.add(n.text); | |
| 22 } | |
| 23 } | |
| 24 return out; | |
| 25 }; | |
| 26 | |
| 27 assertConstError(void fn()) { | |
| 28 try { | |
| 29 fn(); | |
| 30 } catch (var e) { | |
| 31 if (e is IllegalAccessException || e is UnsupportedOperationException) { | |
| 32 return; | |
| 33 } | |
| 34 } | |
| 35 Expect.fail('Expected immutability error'); | |
| 36 }; | |
| 37 | |
| 38 void expectEmptyStyleDeclaration(CSSStyleDeclaration style) { | |
| 39 Expect.equals("", style.cssText); | |
| 40 Expect.equals("", style.getPropertyPriority('color')); | |
| 41 Expect.equals("", style.item(0)); | |
| 42 Expect.equals(0, style.length); | |
| 43 // TODO(jacobr): these checks throw NotImplementedExceptions in dartium. | |
| 44 // Expect.isNull(style.parentRule); | |
| 45 // Expect.isNull(style.getPropertyCSSValue('color')); | |
| 46 // Expect.isNull(style.getPropertyShorthand('color')); | |
| 47 // Expect.isFalse(style.isPropertyImplicit('color')); | |
| 48 | |
| 49 // Ideally these would throw errors, but it's not possible to create a class | |
| 50 // that'll intercept these calls without implementing the entire | |
| 51 // CSSStyleDeclaration interface, so we'll settle for them being no-ops. | |
| 52 style.cssText = '* {color: blue}'; | |
| 53 style.removeProperty('color'); | |
| 54 style.setProperty('color', 'blue'); | |
| 55 } | |
| 56 | |
| 57 group('constructors', () { | |
| 58 test('0-argument makes an empty fragment', () { | |
| 59 final fragment = new DocumentFragment(); | |
| 60 Expect.listEquals([], fragment.elements); | |
| 61 }); | |
| 62 | |
| 63 test('.html parses input as HTML', () { | |
| 64 final fragment = new DocumentFragment.html('<a>foo</a>'); | |
| 65 Expect.isTrue(fragment.elements.first is AnchorElement); | |
| 66 }); | |
| 67 | |
| 68 // test('.svg parses input as SVG', () { | |
| 69 // final fragment = new DocumentFragment.svg('<a>foo</a>'); | |
| 70 // Expect.isTrue(fragment.elements.first is SVGAElement); | |
| 71 // }); | |
| 72 | |
| 73 // TODO(nweiz): enable this once XML is ported. | |
| 74 // test('.xml parses input as XML', () { | |
| 75 // final fragment = new DocumentFragment.xml('<a>foo</a>'); | |
| 76 // Expect.isTrue(fragment.elements.first is XMLElement); | |
| 77 // }); | |
| 78 }); | |
| 79 | |
| 80 test('Unsupported operations throw errors', () { | |
| 81 var emptyFragment = new DocumentFragment(); | |
| 82 expectUnsupported(() => emptyFragment.attributes = {}); | |
| 83 expectUnsupported(() => emptyFragment.classes = []); | |
| 84 expectUnsupported(() => emptyFragment.dataAttributes = {}); | |
| 85 expectUnsupported(() => emptyFragment.contentEditable = "true"); | |
| 86 expectUnsupported(() => emptyFragment.dir); | |
| 87 expectUnsupported(() => emptyFragment.dir = "ltr"); | |
| 88 expectUnsupported(() => emptyFragment.draggable = true); | |
| 89 expectUnsupported(() => emptyFragment.hidden = true); | |
| 90 expectUnsupported(() => emptyFragment.id = "foo"); | |
| 91 expectUnsupported(() => emptyFragment.lang); | |
| 92 expectUnsupported(() => emptyFragment.lang = "en"); | |
| 93 expectUnsupported(() => emptyFragment.scrollLeft = 10); | |
| 94 expectUnsupported(() => emptyFragment.scrollTop = 10); | |
| 95 expectUnsupported(() => emptyFragment.spellcheck = true); | |
| 96 expectUnsupported(() => emptyFragment.translate = true); | |
| 97 expectUnsupported(() => emptyFragment.tabIndex = 5); | |
| 98 expectUnsupported(() => emptyFragment.title = "foo"); | |
| 99 expectUnsupported(() => emptyFragment.webkitdropzone = "foo"); | |
| 100 expectUnsupported(() => emptyFragment.webkitRegionOverflow = "foo"); | |
| 101 }); | |
| 102 | |
| 103 group('elements', () { | |
| 104 var fragment; | |
| 105 var elements; | |
| 106 | |
| 107 init() { | |
| 108 fragment = new DocumentFragment(); | |
| 109 elements = fragment.elements; | |
| 110 fragment.nodes.addAll( | |
| 111 [new Text("1"), new Element.tag("A"), new Element.tag("B"), | |
| 112 new Text("2"), new Element.tag("I"), new Text("3"), | |
| 113 new Element.tag("U")]); | |
| 114 }; | |
| 115 | |
| 116 test('is initially empty', () { | |
| 117 elements = new DocumentFragment().elements; | |
| 118 Expect.listEquals([], elements); | |
| 119 Expect.isTrue(elements.isEmpty()); | |
| 120 }); | |
| 121 | |
| 122 test('filters out non-element nodes', () { | |
| 123 init(); | |
| 124 Expect.listEquals(["1", "A", "B", "2", "I", "3", "U"], | |
| 125 _nodeStrings(fragment.nodes)); | |
| 126 Expect.listEquals(["A", "B", "I", "U"], _nodeStrings(elements)); | |
| 127 }); | |
| 128 | |
| 129 test('only indexes elements, not other nodes', () { | |
| 130 init(); | |
| 131 elements[1] = new Element.tag("BR"); | |
| 132 Expect.listEquals(["1", "A", "BR", "2", "I", "3", "U"], | |
| 133 _nodeStrings(fragment.nodes)); | |
| 134 Expect.listEquals(["A", "BR", "I", "U"], _nodeStrings(elements)); | |
| 135 }); | |
| 136 | |
| 137 test('adds to both elements and nodes', () { | |
| 138 init(); | |
| 139 elements.add(new Element.tag("UL")); | |
| 140 Expect.listEquals(["1", "A", "B", "2", "I", "3", "U", "UL"], | |
| 141 _nodeStrings(fragment.nodes)); | |
| 142 Expect.listEquals(["A", "B", "I", "U", "UL"], _nodeStrings(elements)); | |
| 143 }); | |
| 144 | |
| 145 test('removes only elements, from both elements and nodes', () { | |
| 146 init(); | |
| 147 Expect.equals("U", elements.removeLast().tagName); | |
| 148 Expect.listEquals(["1", "A", "B", "2", "I", "3"], | |
| 149 _nodeStrings(fragment.nodes)); | |
| 150 Expect.listEquals(["A", "B", "I"], _nodeStrings(elements)); | |
| 151 | |
| 152 Expect.equals("I", elements.removeLast().tagName); | |
| 153 Expect.listEquals(["1", "A", "B", "2", "3"], | |
| 154 _nodeStrings(fragment.nodes)); | |
| 155 Expect.listEquals(["A", "B"], _nodeStrings(elements)); | |
| 156 }); | |
| 157 | |
| 158 test('accessors are wrapped', () { | |
| 159 init(); | |
| 160 Expect.equals("A", elements.first.tagName); | |
| 161 Expect.listEquals( | |
| 162 ["I"], _nodeStrings(elements.filter((e) => e.tagName == "I"))); | |
| 163 Expect.isTrue(elements.every((e) => e is Element)); | |
| 164 Expect.isTrue(elements.some((e) => e.tagName == "U")); | |
| 165 Expect.isFalse(elements.isEmpty()); | |
| 166 Expect.equals(4, elements.length); | |
| 167 Expect.equals("I", elements[2].tagName); | |
| 168 Expect.equals("U", elements.last().tagName); | |
| 169 }); | |
| 170 | |
| 171 test('setting elements overwrites nodes as well', () { | |
| 172 init(); | |
| 173 fragment.elements = [new Element.tag("DIV"), new Element.tag("HEAD")]; | |
| 174 Expect.listEquals(["DIV", "HEAD"], _nodeStrings(fragment.nodes)); | |
| 175 }); | |
| 176 }); | |
| 177 | |
| 178 test('setting innerHTML works', () { | |
| 179 var fragment = new DocumentFragment(); | |
| 180 fragment.nodes.add(new Text("foo")); | |
| 181 fragment.innerHTML = "<a>bar</a>baz"; | |
| 182 Expect.listEquals(["A", "baz"], _nodeStrings(fragment.nodes)); | |
| 183 }); | |
| 184 | |
| 185 test('getting innerHTML works', () { | |
| 186 var fragment = new DocumentFragment(); | |
| 187 fragment.nodes.addAll([new Text("foo"), new Element.html("<A>bar</A>")]); | |
| 188 Expect.equals("foo<a>bar</a>", fragment.innerHTML); | |
| 189 Expect.equals("foo<a>bar</a>", fragment.outerHTML); | |
| 190 }); | |
| 191 | |
| 192 group('insertAdjacentElement', () { | |
| 193 getFragment() => new DocumentFragment.html("<a>foo</a>"); | |
| 194 | |
| 195 test('beforeBegin does nothing', () { | |
| 196 var fragment = getFragment(); | |
| 197 Expect.isNull( | |
| 198 fragment.insertAdjacentElement("beforeBegin", new Element.tag("b"))); | |
| 199 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 200 }); | |
| 201 | |
| 202 test('afterEnd does nothing', () { | |
| 203 var fragment = getFragment(); | |
| 204 Expect.isNull( | |
| 205 fragment.insertAdjacentElement("afterEnd", new Element.tag("b"))); | |
| 206 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 207 }); | |
| 208 | |
| 209 test('afterBegin inserts the element', () { | |
| 210 var fragment = getFragment(); | |
| 211 var el = new Element.tag("b"); | |
| 212 Expect.equals(el, fragment.insertAdjacentElement("afterBegin", el)); | |
| 213 Expect.equals("<b></b><a>foo</a>", fragment.innerHTML); | |
| 214 }); | |
| 215 | |
| 216 test('beforeEnd inserts the element', () { | |
| 217 var fragment = getFragment(); | |
| 218 var el = new Element.tag("b"); | |
| 219 Expect.equals(el, fragment.insertAdjacentElement("beforeEnd", el)); | |
| 220 Expect.equals("<a>foo</a><b></b>", fragment.innerHTML); | |
| 221 }); | |
| 222 }); | |
| 223 | |
| 224 group('insertAdjacentText', () { | |
| 225 getFragment() => new DocumentFragment.html("<a>foo</a>"); | |
| 226 | |
| 227 test('beforeBegin does nothing', () { | |
| 228 var fragment = getFragment(); | |
| 229 fragment.insertAdjacentText("beforeBegin", "foo"); | |
| 230 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 231 }); | |
| 232 | |
| 233 test('afterEnd does nothing', () { | |
| 234 var fragment = getFragment(); | |
| 235 fragment.insertAdjacentText("afterEnd", "foo"); | |
| 236 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 237 }); | |
| 238 | |
| 239 test('afterBegin inserts the text', () { | |
| 240 var fragment = getFragment(); | |
| 241 fragment.insertAdjacentText("afterBegin", "foo"); | |
| 242 Expect.equals("foo<a>foo</a>", fragment.innerHTML); | |
| 243 }); | |
| 244 | |
| 245 test('beforeEnd inserts the text', () { | |
| 246 var fragment = getFragment(); | |
| 247 fragment.insertAdjacentText("beforeEnd", "foo"); | |
| 248 Expect.equals("<a>foo</a>foo", fragment.innerHTML); | |
| 249 }); | |
| 250 }); | |
| 251 | |
| 252 group('insertAdjacentHTML', () { | |
| 253 getFragment() => new DocumentFragment.html("<a>foo</a>"); | |
| 254 | |
| 255 test('beforeBegin does nothing', () { | |
| 256 var fragment = getFragment(); | |
| 257 fragment.insertAdjacentHTML("beforeBegin", "foo<br>"); | |
| 258 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 259 }); | |
| 260 | |
| 261 test('afterEnd does nothing', () { | |
| 262 var fragment = getFragment(); | |
| 263 fragment.insertAdjacentHTML("afterEnd", "<br>foo"); | |
| 264 Expect.equals("<a>foo</a>", fragment.innerHTML); | |
| 265 }); | |
| 266 | |
| 267 test('afterBegin inserts the HTML', () { | |
| 268 var fragment = getFragment(); | |
| 269 fragment.insertAdjacentHTML("afterBegin", "foo<br>"); | |
| 270 Expect.equals("foo<br><a>foo</a>", fragment.innerHTML); | |
| 271 }); | |
| 272 | |
| 273 test('beforeEnd inserts the HTML', () { | |
| 274 var fragment = getFragment(); | |
| 275 fragment.insertAdjacentHTML("beforeEnd", "<br>foo"); | |
| 276 Expect.equals("<a>foo</a><br>foo", fragment.innerHTML); | |
| 277 }); | |
| 278 }); | |
| 279 | |
| 280 // Just test that these methods don't throw errors | |
| 281 test("no-op methods don't throw errors", () { | |
| 282 var fragment = new DocumentFragment(); | |
| 283 fragment.on.click.add((e) => null); | |
| 284 fragment.blur(); | |
| 285 fragment.focus(); | |
| 286 fragment.click(); | |
| 287 fragment.scrollByLines(2); | |
| 288 fragment.scrollByPages(2); | |
| 289 fragment.scrollIntoView(); | |
| 290 fragment.webkitRequestFullScreen(2); | |
| 291 }); | |
| 292 | |
| 293 asyncTest('default values', 1, () { | |
| 294 var fragment = new DocumentFragment(); | |
| 295 fragment.rect.then((ElementRect rect) { | |
| 296 expectEmptyRect(rect.client); | |
| 297 expectEmptyRect(rect.offset); | |
| 298 expectEmptyRect(rect.scroll); | |
| 299 expectEmptyRect(rect.bounding); | |
| 300 Expect.isTrue(rect.clientRects.isEmpty()); | |
| 301 callbackDone(); | |
| 302 }); | |
| 303 Expect.equals("false", fragment.contentEditable); | |
| 304 Expect.equals(-1, fragment.tabIndex); | |
| 305 Expect.equals("", fragment.id); | |
| 306 Expect.equals("", fragment.title); | |
| 307 Expect.equals("", fragment.tagName); | |
| 308 Expect.equals("", fragment.webkitdropzone); | |
| 309 Expect.equals("", fragment.webkitRegionOverflow); | |
| 310 Expect.isFalse(fragment.isContentEditable); | |
| 311 Expect.isFalse(fragment.draggable); | |
| 312 Expect.isFalse(fragment.hidden); | |
| 313 Expect.isFalse(fragment.spellcheck); | |
| 314 Expect.isFalse(fragment.translate); | |
| 315 Expect.isNull(fragment.nextElementSibling); | |
| 316 Expect.isNull(fragment.previousElementSibling); | |
| 317 Expect.isNull(fragment.offsetParent); | |
| 318 Expect.isNull(fragment.parent); | |
| 319 Expect.isTrue(fragment.attributes.isEmpty()); | |
| 320 Expect.isTrue(fragment.classes.isEmpty()); | |
| 321 Expect.isTrue(fragment.dataAttributes.isEmpty()); | |
| 322 Expect.isFalse(fragment.matchesSelector("foo")); | |
| 323 Expect.isFalse(fragment.matchesSelector("*")); | |
| 324 }); | |
| 325 | |
| 326 asyncTest('style', 1, () { | |
| 327 var fragment = new DocumentFragment(); | |
| 328 var style = fragment.style; | |
| 329 expectEmptyStyleDeclaration(style); | |
| 330 fragment.computedStyle.then((computedStyle) { | |
| 331 expectEmptyStyleDeclaration(computedStyle); | |
| 332 callbackDone(); | |
| 333 }); | |
| 334 }); | |
| 335 | |
| 336 // TODO(nweiz): re-enable when const is better supported in dartc and/or frog | |
| 337 // test('const fields are immutable', () { | |
| 338 // var fragment = new DocumentFragment(); | |
| 339 // assertConstError(() => fragment.attributes['title'] = 'foo'); | |
| 340 // assertConstError(() => fragment.dataAttributes['title'] = 'foo'); | |
| 341 // fragment.rect.then((ElementRect rect) { | |
| 342 // assertConstError(() => rect.clientRects.add(null)); | |
| 343 // callbackDone(); | |
| 344 // }); | |
| 345 // // Issue 174: #classes is currently not const | |
| 346 // // assertConstError(() => fragment.classes.add('foo')); | |
| 347 // }); | |
| 348 | |
| 349 test('query searches the fragment', () { | |
| 350 var fragment = new DocumentFragment.html( | |
| 351 "<div class='foo'><a>foo</a><b>bar</b></div>"); | |
| 352 Expect.equals("A", fragment.query(".foo a").tagName); | |
| 353 Expect.listEquals(["A", "B"], _nodeStrings(fragment.queryAll(".foo *"))); | |
| 354 }); | |
| 355 } | |
| OLD | NEW |