def test_is_attr(self): '''``is`` is a reserved word for python, so use ``is_`` in constructor. ''' elm = Element('tag', is_='elm') self.assertIn('is', elm.attributes) self.assertNotIn('is_', elm.attributes) self.assertEqual('elm', elm.getAttribute('is')) self.assertIsNone(elm.getAttribute('is_')) # ``is_`` is not treated as special at setAttribute elm.setAttribute('is_', 'new') self.assertEqual('elm', elm.getAttribute('is')) self.assertEqual('new', elm.getAttribute('is_'))
def test_init_attrs(self): elm = Element('a', src='b', href='c') self.assertFalse(elm.hasChildNodes()) self.assertTrue(elm.hasAttributes()) self.assertTrue(elm.getAttribute('src'), 'b') self.assertTrue(elm.getAttribute('href'), 'c')
class TestElement(TestCase): def setUp(self): customElements.clear() self.elm = Element('tag') self.c1 = Element('c1') self.c2 = Element('c2') self.c1.classList.add('c1') self.c2.classList.add('c2') def tearDown(self): del self.elm del self.c1 del self.c2 super().tearDown() def test_constructor(self): elm = Element('a') self.assertEqual(elm.nodeName, 'A') self.assertEqual(elm.tagName, 'A') self.assertEqual(elm.localName, 'a') self.assertFalse(elm.hasChildNodes()) self.assertFalse(elm.hasAttributes()) def test_init_parent(self): elm = Element('a', parent=self.elm) self.assertIs(elm.parentNode, self.elm) def test_init_attrs(self): elm = Element('a', src='b', href='c') self.assertFalse(elm.hasChildNodes()) self.assertTrue(elm.hasAttributes()) self.assertTrue(elm.getAttribute('src'), 'b') self.assertTrue(elm.getAttribute('href'), 'c') def test_attrs(self): self.assertFalse(self.elm.hasAttributes()) self.assertFalse(self.elm.hasAttribute('src')) self.assertNotIn('src', self.elm.attributes) self.assertIsNone(self.elm.getAttribute('src')) self.assertEqual(self.elm.html, '<tag></tag>') self.elm.setAttribute('src', 'a') self.assertTrue(self.elm.hasAttributes()) self.assertTrue(self.elm.hasAttribute('src')) self.assertIn('src', self.elm.attributes) self.assertEqual(self.elm.getAttribute('src'), 'a') self.assertEqual(self.elm.html, '<tag src="a"></tag>') self.elm.removeAttribute('src') self.assertFalse(self.elm.hasAttributes()) self.assertFalse(self.elm.hasAttribute('src')) self.assertNotIn('src', self.elm.attributes) self.assertIsNone(self.elm.getAttribute('src')) self.assertEqual(self.elm.html, '<tag></tag>') def test_id(self): self.assertEqual(self.elm.id, '') self.elm.setAttribute('id', 'a') self.assertEqual(self.elm.getAttribute('id'), 'a') self.assertEqual(self.elm.id, 'a') self.elm.id = 'b' self.assertEqual(self.elm.getAttribute('id'), 'b') self.assertEqual(self.elm.id, 'b') def test_class_list(self): self.assertIsNone(self.elm.getAttribute('class')) self.assertFalse(self.elm.hasAttribute('class')) self.assertFalse(self.elm.hasAttributes()) self.elm.setAttribute('class', 'a') self.assertEqual(self.elm.getAttribute('class'), 'a') self.assertTrue(self.elm.hasAttribute('class')) self.assertTrue(self.elm.hasAttributes()) self.elm.removeAttribute('class') self.assertIsNone(self.elm.getAttribute('class')) self.assertFalse(self.elm.hasAttribute('class')) self.assertFalse(self.elm.hasAttributes()) def test_start_tag(self): self.assertEqual(self.elm.start_tag, '<tag>') self.elm.setAttribute('src', 'a') self.assertEqual(self.elm.start_tag, '<tag src="a">') self.elm.setAttribute('class', 'b') self.assertEqual(self.elm.start_tag, '<tag src="a" class="b">') self.elm.id = 'c' self.assertIn('src="a"', self.elm.start_tag) self.assertIn('id="c"', self.elm.start_tag) def test_inner_html(self): self.assertEqual(self.elm.innerHTML, '') self.elm.appendChild(Element('a')) self.assertEqual(self.elm.innerHTML, '<a></a>') self.elm.innerHTML = '<b></b>' self.assertEqual(self.elm.innerHTML, '<b></b>') self.assertEqual(self.elm.firstChild.tag, 'b') self.assertTrue(isinstance(self.elm.firstChild, HTMLElement)) def test_inner_html_nest(self): html = '<b><c>d</c>e</b>' self.elm.innerHTML = html self.assertEqual(self.elm.innerHTML, html) self.assertEqual(self.elm.firstChild.html, html) self.assertEqual(self.elm.firstChild.firstChild.html, '<c>d</c>') self.assertEqual(self.elm.firstChild.firstChild.innerHTML, 'd') self.assertEqual(self.elm.firstChild.lastChild.html, 'e') self.assertTrue(isinstance(self.elm.firstChild.lastChild, Text)) def test_parse_html_text(self): html = ''' <a>a1</a1> b ''' self.elm.innerHTML = html # fisrt node is empty (\n+spaces) text node self.assertEqual(self.elm.childNodes.length, 3) self.assertTrue(isinstance(self.elm.firstChild, Text)) self.assertTrue(isinstance(self.elm.lastChild, Text)) self.assertTrue(isinstance(self.elm.firstElementChild, HTMLElement)) self.assertTrue(isinstance(self.elm.lastElementChild, HTMLElement)) def test_insert_adjacent_html(self): self.elm.appendChild(self.c1) self.c1.insertAdjacentHTML('beforebegin', '<a></a>') self.assertEqual(self.elm.childNodes.length, 2) self.assertIs(self.elm.lastElementChild, self.c1) self.c1.insertAdjacentHTML('afterend', 'text') self.assertEqual(self.elm.childNodes.length, 3) self.assertIs(self.elm.lastElementChild, self.c1) self.c1.insertAdjacentHTML('afterBegin', '<b></b>') self.assertEqual(self.c1.childNodes.length, 1) self.c1.insertAdjacentHTML('BeforeEnd', '<c></c>') self.assertEqual(self.c1.childNodes.length, 2) with self.assertRaises(ValueError): self.c1.insertAdjacentHTML('a', 'b') def test_end_tag(self): self.assertEqual(self.elm.end_tag, '</tag>') def test_html(self): self.assertEqual(self.elm.html, '<tag></tag>') def test_append_string(self): with self.assertRaises(TypeError): self.elm.appendChild('a') self.assertFalse(self.elm.hasChildNodes()) def test_get_elements_by_tagname(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) c1_tags = self.elm.getElementsByTagName('c1') c2_tags = self.elm.getElementsByTagName('c2') self.assertEqual(len(c1_tags), 1) self.assertEqual(len(c2_tags), 1) self.assertIs(c1_tags[0], self.c1) self.assertIs(c2_tags[0], self.c2) def test_get_elements_by_tagname_nest(self): self.elm.appendChild(self.c1) self.c1.appendChild(self.c2) c2_tags = self.c1.getElementsByTagName('c2') self.assertEqual(len(c2_tags), 1) self.assertIs(c2_tags[0], self.c2) c2_tags = self.elm.getElementsByTagName('c2') self.assertEqual(len(c2_tags), 1) self.assertIs(c2_tags[0], self.c2) def test_get_elements_by_tagname_self(self): c1_tags = self.c1.getElementsByTagName('c1') self.assertEqual(len(c1_tags), 0) def test_get_elements_by_classname(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) c1_classes = self.elm.getElementsByClassName('c1') c2_classes = self.elm.getElementsByClassName('c2') self.assertEqual(len(c1_classes), 1) self.assertEqual(len(c2_classes), 1) self.assertIs(c1_classes[0], self.c1) self.assertIs(c2_classes[0], self.c2) def test_get_elements_by_classname_nest(self): self.elm.appendChild(self.c1) self.c1.appendChild(self.c2) c2_classes = self.c1.getElementsByClassName('c2') self.assertEqual(len(c2_classes), 1) self.assertIs(c2_classes[0], self.c2) c2_classes = self.elm.getElementsByClassName('c2') self.assertEqual(len(c2_classes), 1) self.assertIs(c2_classes[0], self.c2) def test_clone_shallow_child(self): self.elm.appendChild(self.c1) clone = self.elm.cloneNode() self.assertFalse(clone.hasChildNodes()) clone.appendChild(self.c2) self.assertFalse(self.c2 in self.elm) self.assertEqual(len(self.elm.childNodes), 1) def test_clone_shallow_attr(self): self.elm.setAttribute('src', 'a') clone = self.elm.cloneNode() self.assertTrue(clone.hasAttribute('src')) self.assertTrue(clone.getAttribute('src'), 'a') self.assertEqual(self.elm.attributes.toString(), clone.attributes.toString()) clone.setAttribute('src', 'b') self.assertNotEqual(self.elm.attributes.toString(), clone.attributes.toString()) self.assertTrue(self.elm.getAttribute('src'), 'a') self.assertTrue(clone.getAttribute('src'), 'b') def test_clone_deep_child(self): self.elm.appendChild(self.c1) clone = self.elm.cloneNode(deep=True) self.assertTrue(clone.hasChildNodes()) self.assertEqual(len(clone.childNodes), 1) self.assertTrue(self.c1 in self.elm) self.assertFalse(self.c1 in clone) self.assertIsNot(self.c1, clone.firstChild) clone.appendChild(self.c2) self.assertFalse(self.c2 in self.elm) self.assertEqual(len(self.elm.childNodes), 1) self.assertEqual(len(clone.childNodes), 2) def test_clone_deep_attr(self): self.elm.setAttribute('src', 'a') self.elm.appendChild(self.c1) self.c1.setAttribute('src', 'c1') clone = self.elm.cloneNode(deep=True) self.assertTrue(clone.hasAttribute('src')) self.assertTrue(clone.getAttribute('src'), 'a') self.assertTrue(clone.firstChild.hasAttribute('src')) self.assertTrue(clone.firstChild.getAttribute('src'), 'c1') self.assertEqual(self.elm.attributes.toString(), clone.attributes.toString()) self.assertEqual(self.c1.attributes.toString(), clone.firstChild.attributes.toString()) clone.firstChild.setAttribute('src', 'b') self.assertNotEqual(self.c1.attributes.toString(), clone.firstChild.attributes.toString()) self.assertTrue(self.c1.getAttribute('src'), 'a') self.assertTrue(clone.firstChild.getAttribute('src'), 'b') def test_init_class(self): elm = Element('a', class_='a') self.assertEqual(elm.html, '<a class="a"></a>') self.assertEqual(elm.classList.length, 1) self.assertIn('a', elm.classList) elm2 = Element('a', **{'class': 'b'}) self.assertEqual(elm2.html, '<a class="b"></a>') self.assertEqual(elm2.classList.length, 1) self.assertIn('b', elm2.classList) def test_init_class_multi_str(self): elm = Element('a', class_='a1 a2') self.assertEqual(elm.html, '<a class="a1 a2"></a>') self.assertEqual(elm.classList.length, 2) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertNotIn('a1 a2', elm.classList) def test_init_class_multi_list(self): elm = Element('a', class_=['a1', 'a2']) self.assertEqual(elm.html, '<a class="a1 a2"></a>') self.assertEqual(elm.classList.length, 2) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertNotIn('a1 a2', elm.classList) def test_init_class_multi_mixed(self): elm = Element('a', class_=['a1', 'a2 a3']) self.assertEqual(elm.html, '<a class="a1 a2 a3"></a>') self.assertEqual(elm.classList.length, 3) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertIn('a3', elm.classList) self.assertNotIn('a2 a3', elm.classList) def test_reference(self): gc.collect() elm = Element('a') _id = id(elm) self.assertIn(elm, Element._elements) del elm gc.collect() # run gc for elm in Element._elements: assert id(elm) != _id def test_reference_with_id(self): gc.collect() elm = Element('a', id='a') _id = id(elm) self.assertIn(elm.id, Element._elements_with_id) del elm gc.collect() self.assertNotIn('a', Element._elements_with_id) for elm in Element._elements: assert id(elm) != _id def test_reference_add_id(self): gc.collect() elm = Element('a') _id = id(elm) self.assertNotIn(elm, Element._elements_with_id.values()) elm.id = 'a' self.assertIn('a', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.id = 'b' self.assertNotIn('a', Element._elements_with_id) self.assertIn('b', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.setAttribute('id', 'c') self.assertNotIn('b', Element._elements_with_id) self.assertIn('c', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) del elm gc.collect() self.assertNotIn('c', Element._elements_with_id) for elm in Element._elements: assert id(elm) != _id def test_reference_del_id(self): gc.collect() elm = Element('a', id='a') self.assertIn('a', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.removeAttribute('id') self.assertNotIn('a', Element._elements_with_id) self.assertNotIn(elm, Element._elements_with_id.values()) def test_is_attr(self): '''``is`` is a reserved word for python, so use ``is_`` in constructor. ''' elm = Element('tag', is_='elm') self.assertIn('is', elm.attributes) self.assertNotIn('is_', elm.attributes) self.assertEqual('elm', elm.getAttribute('is')) self.assertIsNone(elm.getAttribute('is_')) # ``is_`` is not treated as special at setAttribute elm.setAttribute('is_', 'new') self.assertEqual('elm', elm.getAttribute('is')) self.assertEqual('new', elm.getAttribute('is_')) class NewTag(HTMLElement): pass def test_custom_tag(self): self.elm.innerHTML = '<new-tag></new-tag>' child = self.elm.firstChild self.assertEqual(child.__class__, HTMLElement) customElements.define('new-tag', self.NewTag) self.assertEqual(child.__class__, self.NewTag) def test_custom_tag_registered(self): customElements.define('new-tag', self.NewTag) self.elm.innerHTML = '<new-tag></new-tag>' self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_custom_tag_is(self): self.elm.innerHTML = '<a is="my-a"></a>' child = self.elm.firstChild self.assertEqual(child.__class__, HTMLElement) self.assertEqual(child.getAttribute('is'), 'my-a') customElements.define('my-a', self.NewTag, {'extends': 'a'}) self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_custom_tag_is_registered(self): customElements.define('my-a', self.NewTag, {'extends': 'a'}) self.elm.innerHTML = '<a is="my-a"></a>' self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_invalid_define_args(self): with self.assertRaises(TypeError): customElements.define(1, 2, 3)
class TestElement(TestCase): def setUp(self): customElements.clear() self.elm = Element('tag') self.c1 = Element('c1') self.c2 = Element('c2') self.c1.classList.add('c1') self.c2.classList.add('c2') def tearDown(self): del self.elm del self.c1 del self.c2 super().tearDown() def test_constructor(self): elm = Element('a') self.assertEqual(elm.nodeName, 'A') self.assertEqual(elm.tagName, 'A') self.assertEqual(elm.localName, 'a') self.assertFalse(elm.hasChildNodes()) self.assertFalse(elm.hasAttributes()) def test_init_parent(self): elm = Element('a', parent=self.elm) self.assertIs(elm.parentNode, self.elm) def test_init_attrs(self): elm = Element('a', src='b', href='c') self.assertFalse(elm.hasChildNodes()) self.assertTrue(elm.hasAttributes()) self.assertTrue(elm.getAttribute('src'), 'b') self.assertTrue(elm.getAttribute('href'), 'c') def test_attrs(self): self.assertFalse(self.elm.hasAttributes()) self.assertFalse(self.elm.hasAttribute('src')) self.assertNotIn('src', self.elm.attributes) self.assertIsNone(self.elm.getAttribute('src')) self.assertEqual(self.elm.html, '<tag></tag>') self.elm.setAttribute('src', 'a') self.assertTrue(self.elm.hasAttributes()) self.assertTrue(self.elm.hasAttribute('src')) self.assertIn('src', self.elm.attributes) self.assertEqual(self.elm.getAttribute('src'), 'a') self.assertEqual(self.elm.html, '<tag src="a"></tag>') self.elm.removeAttribute('src') self.assertFalse(self.elm.hasAttributes()) self.assertFalse(self.elm.hasAttribute('src')) self.assertNotIn('src', self.elm.attributes) self.assertIsNone(self.elm.getAttribute('src')) self.assertEqual(self.elm.html, '<tag></tag>') def test_id(self): self.assertEqual(self.elm.id, '') self.elm.setAttribute('id', 'a') self.assertEqual(self.elm.getAttribute('id'), 'a') self.assertEqual(self.elm.id, 'a') self.elm.id = 'b' self.assertEqual(self.elm.getAttribute('id'), 'b') self.assertEqual(self.elm.id, 'b') def test_class_list_str(self): self.assertIsNone(self.elm.getAttribute('class')) self.assertFalse(self.elm.hasAttribute('class')) self.assertFalse(self.elm.hasAttributes()) self.elm.setAttribute('class', 'a') self.assertEqual(self.elm.getAttribute('class'), 'a') self.assertTrue(self.elm.hasAttribute('class')) self.assertTrue(self.elm.hasAttributes()) self.elm.removeAttribute('class') self.assertIsNone(self.elm.getAttribute('class')) self.assertFalse(self.elm.hasAttribute('class')) self.assertFalse(self.elm.hasAttributes()) def test_class_list_list(self): self.elm.setAttribute('class', ['a', 'b']) self.assertEqual(self.elm.getAttribute('class'), 'a b') self.assertTrue(self.elm.hasAttribute('class')) self.assertTrue(self.elm.hasAttributes()) def test_class_name(self): self.assertEqual(self.elm.className, '') self.elm.className = 'a' self.assertEqual(self.elm.className, 'a') self.assertEqual(self.elm.getAttribute('class'), 'a') self.elm.className = 'b c' self.assertEqual(self.elm.className, 'b c') self.assertEqual(self.elm.getAttribute('class'), 'b c') self.assertEqual(self.elm.classList.length, 2) self.elm.className = 'd' self.assertEqual(self.elm.className, 'd') self.assertEqual(self.elm.getAttribute('class'), 'd') self.assertEqual(self.elm.classList.length, 1) with self.assertRaises(TypeError): self.elm.className = ['d'] def test_start_tag(self): self.assertEqual(self.elm.start_tag, '<tag>') self.elm.setAttribute('src', 'a') self.assertEqual(self.elm.start_tag, '<tag src="a">') self.elm.setAttribute('class', 'b') self.assertEqual(self.elm.start_tag, '<tag src="a" class="b">') self.elm.id = 'c' self.assertIn('src="a"', self.elm.start_tag) self.assertIn('id="c"', self.elm.start_tag) def test_inner_html(self): self.assertEqual(self.elm.innerHTML, '') self.elm.appendChild(Element('a')) self.assertEqual(self.elm.innerHTML, '<a></a>') self.elm.innerHTML = '<b></b>' self.assertEqual(self.elm.innerHTML, '<b></b>') self.assertEqual(self.elm.firstChild.tag, 'b') self.assertTrue(isinstance(self.elm.firstChild, Element)) def test_inner_html_nest(self): html = '<b><c>d</c>e</b>' self.elm.innerHTML = html self.assertEqual(self.elm.innerHTML, html) self.assertEqual(self.elm.firstChild.html, html) self.assertEqual(self.elm.firstChild.firstChild.html, '<c>d</c>') self.assertEqual(self.elm.firstChild.firstChild.innerHTML, 'd') self.assertEqual(self.elm.firstChild.lastChild.html, 'e') self.assertTrue(isinstance(self.elm.firstChild.lastChild, Text)) def test_parse_html_text(self): html = ''' <a>a1</a1> b ''' self.elm.innerHTML = html # fisrt node is empty (\n+spaces) text node self.assertEqual(self.elm.childNodes.length, 3) self.assertTrue(isinstance(self.elm.firstChild, Text)) self.assertTrue(isinstance(self.elm.lastChild, Text)) self.assertTrue(isinstance(self.elm.firstElementChild, Element)) self.assertTrue(isinstance(self.elm.lastElementChild, Element)) def test_insert_adjacent_html(self): self.elm.appendChild(self.c1) self.c1.insertAdjacentHTML('beforebegin', '<a></a>') self.assertEqual(self.elm.childNodes.length, 2) self.assertIs(self.elm.lastElementChild, self.c1) self.c1.insertAdjacentHTML('afterend', 'text') self.assertEqual(self.elm.childNodes.length, 3) self.assertIs(self.elm.lastElementChild, self.c1) self.c1.insertAdjacentHTML('afterBegin', '<b></b>') self.assertEqual(self.c1.childNodes.length, 1) self.c1.insertAdjacentHTML('BeforeEnd', '<c></c>') self.assertEqual(self.c1.childNodes.length, 2) with self.assertRaises(ValueError): self.c1.insertAdjacentHTML('a', 'b') def test_end_tag(self): self.assertEqual(self.elm.end_tag, '</tag>') def test_html(self): self.assertEqual(self.elm.html, '<tag></tag>') def test_append_string(self): with self.assertRaises(TypeError): self.elm.appendChild('a') self.assertFalse(self.elm.hasChildNodes()) def test_get_elements_by_tagname(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) c1_tags = self.elm.getElementsByTagName('c1') c2_tags = self.elm.getElementsByTagName('c2') self.assertEqual(len(c1_tags), 1) self.assertEqual(len(c2_tags), 1) self.assertIs(c1_tags[0], self.c1) self.assertIs(c2_tags[0], self.c2) def test_get_elements_by_tagname_nest(self): self.elm.appendChild(self.c1) self.c1.appendChild(self.c2) c2_tags = self.c1.getElementsByTagName('c2') self.assertEqual(len(c2_tags), 1) self.assertIs(c2_tags[0], self.c2) c2_tags = self.elm.getElementsByTagName('c2') self.assertEqual(len(c2_tags), 1) self.assertIs(c2_tags[0], self.c2) def test_get_elements_by_tagname_self(self): c1_tags = self.c1.getElementsByTagName('c1') self.assertEqual(len(c1_tags), 0) def test_get_elements_by_classname(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) c1_classes = self.elm.getElementsByClassName('c1') c2_classes = self.elm.getElementsByClassName('c2') self.assertEqual(len(c1_classes), 1) self.assertEqual(len(c2_classes), 1) self.assertIs(c1_classes[0], self.c1) self.assertIs(c2_classes[0], self.c2) def test_get_elements_by_classname_multi1(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) self.c2.classList.add('c1') c1_classes = self.elm.getElementsByClassName('c1') c2_classes = self.elm.getElementsByClassName('c2') self.assertEqual(len(c1_classes), 2) self.assertEqual(len(c2_classes), 1) def test_get_elements_by_classname_multi2(self): self.elm.appendChild(self.c1) self.elm.appendChild(self.c2) self.c1.classList.add('c3') self.c2.classList.add('c1') self.c2.classList.add('c3') classes1 = self.elm.getElementsByClassName('c1') classes2 = self.elm.getElementsByClassName('c1 c2') classes3 = self.elm.getElementsByClassName('c1 c2 c4') self.assertEqual(len(classes1), 2) self.assertEqual(len(classes2), 1) self.assertEqual(len(classes3), 0) self.assertIs(classes2[0], self.c2) def test_get_elements_by_classname_nest(self): self.elm.appendChild(self.c1) self.c1.appendChild(self.c2) c2_classes = self.c1.getElementsByClassName('c2') self.assertEqual(len(c2_classes), 1) self.assertIs(c2_classes[0], self.c2) c2_classes = self.elm.getElementsByClassName('c2') self.assertEqual(len(c2_classes), 1) self.assertIs(c2_classes[0], self.c2) def test_clone_shallow_child(self): self.elm.appendChild(self.c1) clone = self.elm.cloneNode() self.assertFalse(clone.hasChildNodes()) clone.appendChild(self.c2) self.assertFalse(self.c2 in self.elm) self.assertEqual(len(self.elm.childNodes), 1) def test_clone_shallow_attr(self): self.elm.setAttribute('src', 'a') clone = self.elm.cloneNode() self.assertTrue(clone.hasAttribute('src')) self.assertTrue(clone.getAttribute('src'), 'a') self.assertEqual(self.elm.attributes.toString(), clone.attributes.toString()) clone.setAttribute('src', 'b') self.assertNotEqual(self.elm.attributes.toString(), clone.attributes.toString()) self.assertTrue(self.elm.getAttribute('src'), 'a') self.assertTrue(clone.getAttribute('src'), 'b') def test_clone_deep_child(self): self.elm.appendChild(self.c1) clone = self.elm.cloneNode(deep=True) self.assertTrue(clone.hasChildNodes()) self.assertEqual(len(clone.childNodes), 1) self.assertTrue(self.c1 in self.elm) self.assertFalse(self.c1 in clone) self.assertIsNot(self.c1, clone.firstChild) clone.appendChild(self.c2) self.assertFalse(self.c2 in self.elm) self.assertEqual(len(self.elm.childNodes), 1) self.assertEqual(len(clone.childNodes), 2) def test_clone_deep_attr(self): self.elm.setAttribute('src', 'a') self.elm.appendChild(self.c1) self.c1.setAttribute('src', 'c1') clone = self.elm.cloneNode(deep=True) self.assertTrue(clone.hasAttribute('src')) self.assertTrue(clone.getAttribute('src'), 'a') self.assertTrue(clone.firstChild.hasAttribute('src')) self.assertTrue(clone.firstChild.getAttribute('src'), 'c1') self.assertEqual(self.elm.attributes.toString(), clone.attributes.toString()) self.assertEqual(self.c1.attributes.toString(), clone.firstChild.attributes.toString()) clone.firstChild.setAttribute('src', 'b') self.assertNotEqual(self.c1.attributes.toString(), clone.firstChild.attributes.toString()) self.assertTrue(self.c1.getAttribute('src'), 'a') self.assertTrue(clone.firstChild.getAttribute('src'), 'b') def test_clone_style(self): self.elm.setAttribute('style', 'color: red;') clone = self.elm.cloneNode() self.assertEqual(clone.html, self.elm.html) def test_init_class(self): elm = Element('a', class_='a') self.assertEqual(elm.html, '<a class="a"></a>') self.assertEqual(elm.classList.length, 1) self.assertIn('a', elm.classList) elm2 = Element('a', **{'class': 'b'}) self.assertEqual(elm2.html, '<a class="b"></a>') self.assertEqual(elm2.classList.length, 1) self.assertIn('b', elm2.classList) def test_init_class_multi_str(self): elm = Element('a', class_='a1 a2') self.assertEqual(elm.html, '<a class="a1 a2"></a>') self.assertEqual(elm.classList.length, 2) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertNotIn('a1 a2', elm.classList) def test_init_class_multi_list(self): elm = Element('a', class_=['a1', 'a2']) self.assertEqual(elm.html, '<a class="a1 a2"></a>') self.assertEqual(elm.classList.length, 2) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertNotIn('a1 a2', elm.classList) def test_init_class_multi_mixed(self): elm = Element('a', class_=['a1', 'a2 a3']) self.assertEqual(elm.html, '<a class="a1 a2 a3"></a>') self.assertEqual(elm.classList.length, 3) self.assertIn('a1', elm.classList) self.assertIn('a2', elm.classList) self.assertIn('a3', elm.classList) self.assertNotIn('a2 a3', elm.classList) def test_reference(self): gc.collect() elm = Element('a') _id = id(elm) self.assertIn(elm, Element._element_buffer) del elm gc.collect() # run gc for elm in Element._element_buffer: assert id(elm) != _id def test_reference_with_id(self): gc.collect() elm = Element('a', id='a') _id = id(elm) self.assertIn(elm.id, Element._elements_with_id) del elm gc.collect() self.assertNotIn('a', Element._elements_with_id) for elm in Element._element_buffer: assert id(elm) != _id @skipIf(sys.implementation.name == 'pypy', 'GC not work in PyPy.') def test_reference_add_id(self): gc.collect() elm = Element('a') _id = id(elm) self.assertNotIn(elm, Element._elements_with_id.values()) elm.id = 'a' self.assertIn('a', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.id = 'b' self.assertNotIn('a', Element._elements_with_id) self.assertIn('b', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.setAttribute('id', 'c') self.assertNotIn('b', Element._elements_with_id) self.assertIn('c', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) del elm gc.collect() self.assertNotIn('c', Element._elements_with_id) for elm in Element._element_buffer: assert id(elm) != _id def test_reference_del_id(self): gc.collect() elm = Element('a', id='a') self.assertIn('a', Element._elements_with_id) self.assertIn(elm, Element._elements_with_id.values()) elm.removeAttribute('id') self.assertNotIn('a', Element._elements_with_id) self.assertNotIn(elm, Element._elements_with_id.values()) def test_is_attr(self): '''``is`` is a reserved word for python, so use ``is_`` in constructor. ''' elm = Element('tag', is_='elm') self.assertIn('is', elm.attributes) self.assertNotIn('is_', elm.attributes) self.assertEqual('elm', elm.getAttribute('is')) self.assertIsNone(elm.getAttribute('is_')) # ``is_`` is not treated as special at setAttribute elm.setAttribute('is_', 'new') self.assertEqual('elm', elm.getAttribute('is')) self.assertEqual('new', elm.getAttribute('is_')) class NewTag(HTMLElement): pass def test_custom_tag(self): self.elm.innerHTML = '<new-tag></new-tag>' child = self.elm.firstChild self.assertEqual(child.__class__, Element) customElements.define('new-tag', self.NewTag) self.assertEqual(child.__class__, self.NewTag) def test_custom_tag_registered(self): customElements.define('new-tag', self.NewTag) self.elm.innerHTML = '<new-tag></new-tag>' self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_custom_tag_is(self): self.elm.innerHTML = '<a is="my-a"></a>' child = self.elm.firstChild self.assertEqual(child.__class__, Element) self.assertEqual(child.getAttribute('is'), 'my-a') customElements.define('my-a', self.NewTag, {'extends': 'a'}) self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_custom_tag_is_registered(self): customElements.define('my-a', self.NewTag, {'extends': 'a'}) self.elm.innerHTML = '<a is="my-a"></a>' self.assertEqual(self.elm.firstChild.__class__, self.NewTag) def test_invalid_define_args(self): with self.assertRaises(TypeError): customElements.define(1, 2, 3)