from beautifulsoup.builder.html5lib_builder import HTML5TreeBuilder from beautifulsoup.element import Comment from test_lxml import ( TestLXMLBuilder, TestLXMLBuilderInvalidMarkup, ) class TestHTML5Builder(TestLXMLBuilder): """See `BuilderSmokeTest`.""" @property def default_builder(self): return HTML5TreeBuilder() def test_bare_string(self): # A bare string is turned into some kind of HTML document or # fragment recognizable as the original string. # # In this case, lxml puts a

tag around the bare string. self.assertSoupEquals( "A bare string", "A bare string") def test_correctly_nested_tables(self): markup = ('' '' "') self.assertSoupEquals( markup, '
Here's another table:" '' '' '
foo
Here\'s another table:' '
foo
' '
') self.assertSoupEquals( "" "" "
Foo
Bar
Baz
") def test_collapsed_whitespace(self): """Whitespace is preserved even in tags that don't require it.""" self.assertSoupEquals("

") self.assertSoupEquals(" ") def test_cdata_where_its_ok(self): # In html5lib 0.9.0, all CDATA sections are converted into # comments. In a later version (unreleased as of this # writing), CDATA sections in tags like and will # be preserved. BUT, I'm not sure how Beautiful Soup needs to # adjust to transform this preservation into the construction # of a BS CData object. markup = "foobar" # Eventually we should be able to do a find(text="foobar") and # get a CData object. self.assertSoupEquals(markup, "") class TestHTML5BuilderInvalidMarkup(TestLXMLBuilderInvalidMarkup): """See `BuilderInvalidMarkupSmokeTest`.""" @property def default_builder(self): return HTML5TreeBuilder() def test_unclosed_block_level_elements(self): # The unclosed tag is closed so that the block-level tag # can be closed, and another tag is inserted after the # next block-level tag begins. self.assertSoupEquals( '

Foo

Bar', '

Foo

Bar

') def test_table_containing_bare_markup(self): # Markup should be in table cells, not directly in the table. self.assertSoupEquals("
Foo
", "
Foo
") def test_incorrectly_nested_tables(self): self.assertSoupEquals( '
', ('
' '
')) def test_doctype_in_body(self): markup = "

onetwo

" self.assertSoupEquals(markup, "

onetwo

") def test_cdata_where_it_doesnt_belong(self): # Random CDATA sections are converted into comments. markup = "
" soup = self.soup(markup) data = soup.find(text="[CDATA[foo]]") self.assertEquals(data.__class__, Comment) def test_nonsensical_declaration(self): # Declarations that don't make any sense are turned into comments. soup = self.soup('

a

') self.assertEquals(str(soup), ("" "

a

")) soup = self.soup('

a

') self.assertEquals(str(soup), ("

a

" "")) def test_whitespace_in_doctype(self): # A declaration that has extra whitespace is turned into a comment. soup = self.soup(( '' '

foo

')) self.assertEquals( str(soup), ('' '

foo

')) def test_incomplete_declaration(self): # An incomplete declaration is treated as a comment. markup = 'ac' self.assertSoupEquals(markup, "ac") # Let's spell that out a little more explicitly. soup = self.soup(markup) str1, comment, str2 = soup.body.contents self.assertEquals(str1, 'a') self.assertEquals(comment.__class__, Comment) self.assertEquals(comment, 'b Sacr\xe9 bleu!""" soup = self.soup(isolatin) utf8 = isolatin.replace("ISO-Latin-1".encode(), "utf-8".encode()) utf8 = utf8.replace("\xe9", "\xc3\xa9") #print soup