"""Tests for floating boxes layout.""" import pytest from weasyprint.formatting_structure import boxes from .testing_utils import assert_no_logs, render_pages def outer_area(box): """Return the (x, y, w, h) rectangle for the outer area of a box.""" return (box.position_x, box.position_y, box.margin_width(), box.margin_height()) @assert_no_logs def test_floats_1(): # adjacent-floats-001 page, = render_pages('''
''') html, = page.children body, = html.children div_1, div_2 = body.children assert outer_area(div_1) == (0, 0, 100, 100) assert outer_area(div_2) == (100, 0, 100, 100) @assert_no_logs def test_floats_2(): # c414-flt-fit-000 page, = render_pages('''
''') html, = page.children body, = html.children div_1, div_2, div_4, anon_block = body.children line_3, line_5 = anon_block.children img_3, = line_3.children img_5, = line_5.children assert outer_area(div_1) == (0, 0, 100, 60) assert outer_area(div_2) == (100, 0, 100, 60) assert outer_area(img_3) == (200, 0, 60, 60) assert outer_area(div_4) == (0, 60, 100, 60) assert outer_area(img_5) == (100, 60, 60, 60) @assert_no_logs def test_floats_3(): # c414-flt-fit-002 page, = render_pages('''

⇦ A 1

⇦ B 2

⇦ A 3

B 4 ⇨

⇦ A 5

B 6 ⇨

B 8 ⇨

⇦ A 7

⇦ A 9

⇦ B 10

''') html, = page.children body, = html.children positions = [(paragraph.position_x, paragraph.position_y) for paragraph in body.children] assert positions == [ (0, 0), (70, 0), (0, 20), (130, 20), (0, 40), (130, 40), (130, 60), (0, 60), (0, 80), (70, 80), ] @assert_no_logs def test_floats_4(): # c414-flt-wrap-000 ... more or less page, = render_pages('''

''') html, = page.children body, = html.children p_1, p_2, anon_block = body.children line_1, line_2 = anon_block.children assert anon_block.position_y == 0 assert (line_1.position_x, line_1.position_y) == (20, 0) assert (line_2.position_x, line_2.position_y) == (0, 200) @assert_no_logs def test_floats_5(): # c414-flt-wrap-000 with text ... more or less page, = render_pages('''

A B ''') html, = page.children body, = html.children p_1, p_2, anon_block = body.children line_1, line_2 = anon_block.children assert anon_block.position_y == 0 assert (line_1.position_x, line_1.position_y) == (20, 0) assert (line_2.position_x, line_2.position_y) == (0, 200) @assert_no_logs def test_floats_6(): # floats-placement-vertical-001b page, = render_pages(''' ''') html, = page.children body, = html.children line_1, line_2 = body.children span_1, = line_1.children span_2, = line_2.children img_1, = span_1.children img_2, img_3 = span_2.children assert outer_area(img_1) == (0, 0, 50, 50) assert outer_area(img_2) == (30, 50, 50, 50) assert outer_area(img_3) == (0, 50, 30, 30) @assert_no_logs def test_floats_7(): # Variant of the above: no page, = render_pages(''' ''') html, = page.children body, = html.children line_1, line_2 = body.children img_1, = line_1.children img_2, img_3 = line_2.children assert outer_area(img_1) == (0, 0, 50, 50) assert outer_area(img_2) == (30, 50, 50, 50) assert outer_area(img_3) == (0, 50, 30, 30) @assert_no_logs def test_floats_8(): # Floats do no affect other pages page_1, page_2 = render_pages('''
''') html, = page_1.children body, = html.children float_img, anon_block, = body.children line, = anon_block.children img_1, = line.children assert outer_area(float_img) == (0, 0, 30, 30) assert outer_area(img_1) == (30, 0, 50, 50) html, = page_2.children body, = html.children div, anon_block = body.children line, = anon_block.children img_2, = line.children @assert_no_logs def test_floats_9(): # Regression test # https://github.com/Kozea/WeasyPrint/issues/263 page, = render_pages('''
''') @assert_no_logs def test_floats_page_breaks_1(): # Tests floated images shorter than the page pages = render_pages(''' ''') assert len(pages) == 2 page_images = [] for page in pages: images = [d for d in page.descendants() if d.element_tag == 'img'] assert all([img.element_tag == 'img' for img in images]) assert all([img.position_x == 10 for img in images]) page_images.append(images) positions_y = [[img.position_y for img in images] for images in page_images] assert positions_y == [[10], [10]] @assert_no_logs def test_floats_page_breaks_2(): # Tests floated images taller than the page pages = render_pages(''' ''') assert len(pages) == 2 page_images = [] for page in pages: images = [d for d in page.descendants() if d.element_tag == 'img'] assert all([img.element_tag == 'img' for img in images]) assert all([img.position_x == 10 for img in images]) page_images.append(images) positions_y = [[img.position_y for img in images] for images in page_images] assert positions_y == [[10], [10]] @assert_no_logs def test_floats_page_breaks_3(): # Tests floated images shorter than the page pages = render_pages(''' ''') assert len(pages) == 3 page_images = [] for page in pages: images = [d for d in page.descendants() if d.element_tag == 'img'] assert all([img.element_tag == 'img' for img in images]) assert all([img.position_x == 10 for img in images]) page_images.append(images) positions_y = [[img.position_y for img in images] for images in page_images] assert positions_y == [[10, 40], [10, 40], [10]] @assert_no_logs def test_preferred_widths_1(): def get_float_width(body_width): page, = render_pages('''

Lorem ipsum dolor sit amet, consectetur elit

''' % body_width) html, = page.children body, = html.children paragraph, = body.children return paragraph.width # Preferred minimum width: assert get_float_width(10) == len('consectetur elit') * 16 # Preferred width: assert get_float_width(1000000) == len('Lorem ipsum dolor sit amet,') * 16 @assert_no_logs def test_preferred_widths_2(): # Non-regression test: # Incorrect whitespace handling in preferred width used to cause # unnecessary line break. page, = render_pages('''

Lorem ipsum dolor.

''') html, = page.children body, = html.children paragraph, = body.children assert len(paragraph.children) == 1 assert isinstance(paragraph.children[0], boxes.LineBox) @assert_no_logs def test_preferred_widths_3(): page, = render_pages('''


''') html, = page.children body, = html.children paragraph, = body.children assert paragraph.width == 40 @assert_no_logs def test_preferred_widths_4(): page, = render_pages( '' '

XX
XX
X

') html, = page.children body, = html.children paragraph, = body.children assert paragraph.width == 40 @assert_no_logs def test_preferred_widths_5(): # The space is the start of the line is collapsed. page, = render_pages( '' '

XX
XX
X

') html, = page.children body, = html.children paragraph, = body.children assert paragraph.width == 40 @assert_no_logs def test_float_in_inline_1(): page, = render_pages('''

aa bb cc ddd ee ff

''') html, = page.children body, = html.children paragraph, = body.children line1, line2 = paragraph.children p1, a, p2 = line1.children assert p1.width == 6 * 20 assert p1.text == 'aa bb ' assert p1.position_x == 0 * 20 assert p2.width == 3 * 20 assert p2.text == ' ee' assert p2.position_x == 9 * 20 span, a_text = a.children assert a_text.width == 3 * 20 # leading space collapse assert a_text.text == 'ddd' assert a_text.position_x == 6 * 20 assert span.width == 2 * 20 assert span.children[0].children[0].text == 'cc' assert span.position_x == 12 * 20 p3, = line2.children assert p3.width == 2 * 20 @assert_no_logs def test_float_in_inline_2(): page, = render_pages('''
a b c
1 2 3 4 5 6
''') html, = page.children body, = html.children article, = body.children line1, line2 = article.children span1, = line1.children div, text = span1.children assert div.children[0].children[0].text.strip() == 'a b c' assert text.text.strip() == '1 2 3' span2, = line2.children text, = span2.children assert text.text.strip() == '4 5 6' @assert_no_logs def test_float_in_inline_3(): page, = render_pages('''
1 2 3
a b c
4 5 6
''') html, = page.children body, = html.children article, = body.children line1, line2 = article.children span1, = line1.children text, div = span1.children assert text.text.strip() == '1 2 3' assert div.children[0].children[0].text.strip() == 'a b c' span2, = line2.children text, = span2.children assert text.text.strip() == '4 5 6' @assert_no_logs def test_float_in_inline_4(): page, = render_pages('''
1 2 3 4
a b c
5 6
''') html, = page.children body, = html.children article, = body.children line1, line2 = article.children span1, div = line1.children text1, text2 = span1.children assert text1.text.strip() == '1 2 3 4' assert text2.text.strip() == '5' assert div.position_y == 16 assert div.children[0].children[0].text.strip() == 'a b c' span2, = line2.children text, = span2.children assert text.text.strip() == '6' @assert_no_logs def test_float_next_line(): page, = render_pages('''

pp pp pp pp ppppp aa pp pp pp pp pp

''') html, = page.children body, = html.children paragraph, = body.children line1, line2, line3 = paragraph.children assert len(line1.children) == 1 assert len(line3.children) == 1 a, p = line2.children span, a_text = a.children assert span.position_x == 0 assert span.width == 5 * 20 assert a_text.position_x == a.position_x == 5 * 20 assert a_text.width == a.width == 2 * 20 assert p.position_x == 7 * 20 @assert_no_logs def test_float_text_indent_1(): page, = render_pages('''

aa float aa

''') html, = page.children body, = html.children paragraph, = body.children line1, = paragraph.children a, = line1.children a1, span, a2 = a.children span_text, = span.children assert span.position_x == span_text.position_x == 0 assert span.width == span_text.width == ( (1 + 5) * 20) # text-indent + span text assert a1.width == 3 * 20 assert a1.position_x == (1 + 5 + 1) * 20 # span + a1 text-indent assert a2.width == 2 * 20 # leading space collapse assert a2.position_x == (1 + 5 + 1 + 3) * 20 # span + a1 t-i + a1 @assert_no_logs def test_float_text_indent_2(): page, = render_pages('''

oooooooooooo aa float aa

''') html, = page.children body, = html.children paragraph, = body.children line1, line2 = paragraph.children p1, = line1.children assert p1.position_x == 1 * 20 # text-indent assert p1.width == 12 * 20 # p text a, = line2.children a1, span, a2 = a.children span_text, = span.children assert span.position_x == span_text.position_x == 0 assert span.width == span_text.width == ( (1 + 5) * 20) # text-indent + span text assert a1.width == 3 * 20 assert a1.position_x == (1 + 5) * 20 # span assert a2.width == 2 * 20 # leading space collapse assert a2.position_x == (1 + 5 + 3) * 20 # span + a1 @assert_no_logs def test_float_text_indent_3(): page, = render_pages('''

oooooooooooo aa float aa oooooooooooo

''') html, = page.children body, = html.children paragraph, = body.children line1, line2, line3 = paragraph.children p1, = line1.children assert p1.position_x == 1 * 20 # text-indent assert p1.width == 12 * 20 # p text a, = line2.children a1, span, a2 = a.children span_text, = span.children assert span.position_x == span_text.position_x == (14 - 5 - 1) * 20 assert span.width == span_text.width == ( (1 + 5) * 20) # text-indent + span text assert a1.position_x == 0 # span assert a2.width == 2 * 20 # leading space collapse assert a2.position_x == (14 - 5 - 1 - 2) * 20 p2, = line3.children assert p2.position_x == 0 assert p2.width == 12 * 20 # p text @pytest.mark.xfail @assert_no_logs def test_float_fail(): page, = render_pages('''

bb bb pp bb pp pb pp pp apa bb bb

''') html, = page.children body, = html.children paragraph, = body.children line1, line2, line3 = paragraph.children