diff options
author | Leonard Richardson <leonardr@segfault.org> | 2021-10-11 14:42:01 -0400 |
---|---|---|
committer | Leonard Richardson <leonardr@segfault.org> | 2021-10-11 14:42:01 -0400 |
commit | 242a340e5cf8c13449c9a4d73cf55194536a27d1 (patch) | |
tree | fc839d9825dd2f2bf3782baf1ec6a4ee6c178f75 | |
parent | cf371d4ab99860d96b97b355d5c01a45013f9c42 (diff) |
More test refactoring.
-rw-r--r-- | bs4/tests/test_navigablestring.py | 11 | ||||
-rw-r--r-- | bs4/tests/test_tag.py | 52 | ||||
-rw-r--r-- | bs4/tests/test_tree.py | 42 |
3 files changed, 62 insertions, 43 deletions
diff --git a/bs4/tests/test_navigablestring.py b/bs4/tests/test_navigablestring.py index 37cb86a..2b76392 100644 --- a/bs4/tests/test_navigablestring.py +++ b/bs4/tests/test_navigablestring.py @@ -1,3 +1,5 @@ +import pytest + from bs4.element import ( CData, Comment, @@ -43,7 +45,14 @@ class TestNavigableString(SoupTest): # Unless you specifically say that comments are okay. assert "foe" == comment.get_text(strip=True, types=Comment) assert "foe " == comment.get_text(types=(Comment, NavigableString)) - + + def test_string_has_immutable_name_property(self): + # string.name is defined as None and can't be modified + string = self.soup("s").string + assert None == string.name + with pytest.raises(AttributeError): + string.name = 'foo' + class TestNavigableStringSubclasses(SoupTest): def test_cdata(self): diff --git a/bs4/tests/test_tag.py b/bs4/tests/test_tag.py index 7a6308a..88cc202 100644 --- a/bs4/tests/test_tag.py +++ b/bs4/tests/test_tag.py @@ -167,3 +167,55 @@ class TestTag(SoupTest): assert list(script.div.strings) == ["a"] assert script.div.script.get_text() == "<!--a comment-->Some text" assert list(script.div.script.strings) == ['<!--a comment-->Some text'] + + +class TestMultiValuedAttributes(SoupTest): + """Test the behavior of multi-valued attributes like 'class'. + + The values of such attributes are always presented as lists. + """ + + def test_single_value_becomes_list(self): + soup = self.soup("<a class='foo'>") + assert ["foo"] ==soup.a['class'] + + def test_multiple_values_becomes_list(self): + soup = self.soup("<a class='foo bar'>") + assert ["foo", "bar"] == soup.a['class'] + + def test_multiple_values_separated_by_weird_whitespace(self): + soup = self.soup("<a class='foo\tbar\nbaz'>") + assert ["foo", "bar", "baz"] ==soup.a['class'] + + def test_attributes_joined_into_string_on_output(self): + soup = self.soup("<a class='foo\tbar'>") + assert b'<a class="foo bar"></a>' == soup.a.encode() + + def test_get_attribute_list(self): + soup = self.soup("<a id='abc def'>") + assert ['abc def'] == soup.a.get_attribute_list('id') + + def test_accept_charset(self): + soup = self.soup('<form accept-charset="ISO-8859-1 UTF-8">') + assert ['ISO-8859-1', 'UTF-8'] == soup.form['accept-charset'] + + def test_cdata_attribute_applying_only_to_one_tag(self): + data = '<a accept-charset="ISO-8859-1 UTF-8"></a>' + soup = self.soup(data) + # We saw in another test that accept-charset is a cdata-list + # attribute for the <form> tag. But it's not a cdata-list + # attribute for any other tag. + assert 'ISO-8859-1 UTF-8' == soup.a['accept-charset'] + + def test_customization(self): + # It's possible to change which attributes of which tags + # are treated as multi-valued attributes. + # + # Here, 'id' is a multi-valued attribute and 'class' is not. + # + # TODO: This code is in the builder and should be tested there. + soup = self.soup( + '<a class="foo" id="bar">', multi_valued_attributes={ '*' : 'id' } + ) + assert soup.a['class'] == 'foo' + assert soup.a['id'] == ['bar'] diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py index 43fe284..26c7bbb 100644 --- a/bs4/tests/test_tree.py +++ b/bs4/tests/test_tree.py @@ -1268,45 +1268,3 @@ class TestTreeModification(SoupTest): soup.a.string = cdata assert isinstance(soup.a.string, CData) -class TestCDAtaListAttributes(SoupTest): - - """Testing cdata-list attributes like 'class'. - """ - def test_single_value_becomes_list(self): - soup = self.soup("<a class='foo'>") - assert ["foo"] ==soup.a['class'] - - def test_multiple_values_becomes_list(self): - soup = self.soup("<a class='foo bar'>") - assert ["foo", "bar"] == soup.a['class'] - - def test_multiple_values_separated_by_weird_whitespace(self): - soup = self.soup("<a class='foo\tbar\nbaz'>") - assert ["foo", "bar", "baz"] ==soup.a['class'] - - def test_attributes_joined_into_string_on_output(self): - soup = self.soup("<a class='foo\tbar'>") - assert b'<a class="foo bar"></a>' == soup.a.encode() - - def test_get_attribute_list(self): - soup = self.soup("<a id='abc def'>") - assert ['abc def'] == soup.a.get_attribute_list('id') - - def test_accept_charset(self): - soup = self.soup('<form accept-charset="ISO-8859-1 UTF-8">') - assert ['ISO-8859-1', 'UTF-8'] == soup.form['accept-charset'] - - def test_cdata_attribute_applying_only_to_one_tag(self): - data = '<a accept-charset="ISO-8859-1 UTF-8"></a>' - soup = self.soup(data) - # We saw in another test that accept-charset is a cdata-list - # attribute for the <form> tag. But it's not a cdata-list - # attribute for any other tag. - assert 'ISO-8859-1 UTF-8' == soup.a['accept-charset'] - - def test_string_has_immutable_name_property(self): - string = self.soup("s").string - assert None == string.name - with pytest.raises(AttributeError): - string.name = 'foo' - |