# Path: weasyprint/formatting_structure/boxes.py
# class Box:
# class ParentBox(Box):
# class BlockLevelBox(Box):
# class BlockContainerBox(ParentBox):
# class BlockBox(BlockContainerBox, BlockLevelBox):
# class LineBox(ParentBox):
# class InlineLevelBox(Box):
# class InlineBox(InlineLevelBox, ParentBox):
# class TextBox(InlineLevelBox):
# class AtomicInlineLevelBox(InlineLevelBox):
# class InlineBlockBox(AtomicInlineLevelBox, BlockContainerBox):
# class ReplacedBox(Box):
# class BlockReplacedBox(ReplacedBox, BlockLevelBox):
# class InlineReplacedBox(ReplacedBox, AtomicInlineLevelBox):
# class TableBox(BlockLevelBox, ParentBox):
# class InlineTableBox(TableBox):
# class TableRowGroupBox(ParentBox):
# class TableRowBox(ParentBox):
# class TableColumnGroupBox(ParentBox):
# class TableColumnBox(ParentBox):
# class TableCellBox(BlockContainerBox):
# class TableCaptionBox(BlockBox):
# class PageBox(ParentBox):
# class MarginBox(BlockContainerBox):
# class FootnoteAreaBox(BlockBox):
# class FlexContainerBox(ParentBox):
# class FlexBox(FlexContainerBox, BlockLevelBox):
# class InlineFlexBox(FlexContainerBox, InlineLevelBox):
#     def all_children(self):
#     def __init__(self, element_tag, style, element):
#     def __repr__(self):
#     def anonymous_from(cls, parent, *args, **kwargs):
#     def copy(self):
#     def deepcopy(self):
#     def translate(self, dx=0, dy=0, ignore_floats=False):
#     def padding_width(self):
#     def padding_height(self):
#     def border_width(self):
#     def border_height(self):
#     def margin_width(self):
#     def margin_height(self):
#     def content_box_x(self):
#     def content_box_y(self):
#     def padding_box_x(self):
#     def padding_box_y(self):
#     def border_box_x(self):
#     def border_box_y(self):
#     def hit_area(self):
#     def rounded_box(self, bt, br, bb, bl):
#     def rounded_box_ratio(self, ratio):
#     def rounded_padding_box(self):
#     def rounded_border_box(self):
#     def rounded_content_box(self):
#     def is_floated(self):
#     def is_footnote(self):
#     def is_absolutely_positioned(self):
#     def is_running(self):
#     def is_in_normal_flow(self):
#     def page_values(self):
#     def __init__(self, element_tag, style, element, children):
#     def all_children(self):
#     def _reset_spacing(self, side):
#     def remove_decoration(self, start, end):
#     def copy_with_children(self, new_children):
#     def deepcopy(self):
#     def descendants(self):
#     def get_wrapped_table(self):
#     def page_values(self):
#     def anonymous_from(cls, parent, *args, **kwargs):
#     def remove_decoration(self, start, end):
#     def hit_area(self):
#     def __init__(self, element_tag, style, element, text):
#     def copy_with_text(self, text):
#     def __init__(self, element_tag, style, element, replacement):
#     def all_children(self):
#     def translate(self, dx=0, dy=0, ignore_floats=False):
#     def page_values(self):
#     def get_cells(self):
#     def get_cells(self):
#     def __init__(self, page_type, style):
#     def __repr__(self):
#     def __init__(self, at_keyword, style):
#     def __repr__(self):
#     def __init__(self, page, style):
#     def __repr__(self):
# 
# Path: tests/testing_utils.py
# def assert_no_logs(function):
#     """Decorator that asserts that nothing is logged in a function."""
#     @functools.wraps(function)
#     def wrapper(*args, **kwargs):
#         with capture_logs() as logs:
#             try:
#                 function(*args, **kwargs)
#             except Exception:  # pragma: no cover
#                 if logs:
#                     print(f'{len(logs)} errors logged:', file=sys.stderr)
#                     for message in logs:
#                         print(message, file=sys.stderr)
#                 raise
#             else:
#                 if logs:  # pragma: no cover
#                     for message in logs:
#                         print(message, file=sys.stderr)
#                     raise AssertionError(f'{len(logs)} errors logged')
#     return wrapper
# 
# def render_pages(html_content):
#     """Lay out a document and return a list of PageBox objects."""
#     return [
#         page._page_box for page in
#         FakeHTML(string=html_content, base_url=BASE_URL).render().pages]


import pytest
from weasyprint.formatting_structure import boxes
from ..testing_utils import assert_no_logs, render_pages

@pytest.mark.parametrize('margin_1, margin_2, result', COLLAPSING)
def test_vertical_space_4(margin_1, margin_2, result):
    # Not siblings, second is doubly nested
    page, = render_pages('''
      <style>
        p { font: 20px/1 serif } /* block height == 20px */
        #p1 { margin-bottom: %s }
        #p2 { margin-top: %s }
      </style>
      <p id=p1>Lorem ipsum
      <div>
        <div>
            <p id=p2>dolor sit amet
        </div>
      </div>
    ''' % (margin_1, margin_2))
    html, = page.children
    body, = html.children
    p1, div1 = body.children
    div2, = div1.children
    p2, = div2.children
    p1_bottom = p1.content_box_y() + p1.height
    p2_top = p2.content_box_y()
    assert p2_top - p1_bottom == result


@pytest.mark.parametrize('margin_1, margin_2, result', COLLAPSING)
def test_vertical_space_5(margin_1, margin_2, result):
    # Collapsing with children

# Path: weasyprint/formatting_structure/boxes.py
# class Box:
# class ParentBox(Box):
# class BlockLevelBox(Box):
# class BlockContainerBox(ParentBox):
# class BlockBox(BlockContainerBox, BlockLevelBox):
# class LineBox(ParentBox):
# class InlineLevelBox(Box):
# class InlineBox(InlineLevelBox, ParentBox):
# class TextBox(InlineLevelBox):
# class AtomicInlineLevelBox(InlineLevelBox):
# class InlineBlockBox(AtomicInlineLevelBox, BlockContainerBox):
# class ReplacedBox(Box):
# class BlockReplacedBox(ReplacedBox, BlockLevelBox):
# class InlineReplacedBox(ReplacedBox, AtomicInlineLevelBox):
# class TableBox(BlockLevelBox, ParentBox):
# class InlineTableBox(TableBox):
# class TableRowGroupBox(ParentBox):
# class TableRowBox(ParentBox):
# class TableColumnGroupBox(ParentBox):
# class TableColumnBox(ParentBox):
# class TableCellBox(BlockContainerBox):
# class TableCaptionBox(BlockBox):
# class PageBox(ParentBox):
# class MarginBox(BlockContainerBox):
# class FootnoteAreaBox(BlockBox):
# class FlexContainerBox(ParentBox):
# class FlexBox(FlexContainerBox, BlockLevelBox):
# class InlineFlexBox(FlexContainerBox, InlineLevelBox):
#     def all_children(self):
#     def __init__(self, element_tag, style, element):
#     def __repr__(self):
#     def anonymous_from(cls, parent, *args, **kwargs):
#     def copy(self):
#     def deepcopy(self):
#     def translate(self, dx=0, dy=0, ignore_floats=False):
#     def padding_width(self):
#     def padding_height(self):
#     def border_width(self):
#     def border_height(self):
#     def margin_width(self):
#     def margin_height(self):
#     def content_box_x(self):
#     def content_box_y(self):
#     def padding_box_x(self):
#     def padding_box_y(self):
#     def border_box_x(self):
#     def border_box_y(self):
#     def hit_area(self):
#     def rounded_box(self, bt, br, bb, bl):
#     def rounded_box_ratio(self, ratio):
#     def rounded_padding_box(self):
#     def rounded_border_box(self):
#     def rounded_content_box(self):
#     def is_floated(self):
#     def is_footnote(self):
#     def is_absolutely_positioned(self):
#     def is_running(self):
#     def is_in_normal_flow(self):
#     def page_values(self):
#     def __init__(self, element_tag, style, element, children):
#     def all_children(self):
#     def _reset_spacing(self, side):
#     def remove_decoration(self, start, end):
#     def copy_with_children(self, new_children):
#     def deepcopy(self):
#     def descendants(self):
#     def get_wrapped_table(self):
#     def page_values(self):
#     def anonymous_from(cls, parent, *args, **kwargs):
#     def remove_decoration(self, start, end):
#     def hit_area(self):
#     def __init__(self, element_tag, style, element, text):
#     def copy_with_text(self, text):
#     def __init__(self, element_tag, style, element, replacement):
#     def all_children(self):
#     def translate(self, dx=0, dy=0, ignore_floats=False):
#     def page_values(self):
#     def get_cells(self):
#     def get_cells(self):
#     def __init__(self, page_type, style):
#     def __repr__(self):
#     def __init__(self, at_keyword, style):
#     def __repr__(self):
#     def __init__(self, page, style):
#     def __repr__(self):
# 
# Path: tests/testing_utils.py
# def assert_no_logs(function):
#     """Decorator that asserts that nothing is logged in a function."""
#     @functools.wraps(function)
#     def wrapper(*args, **kwargs):
#         with capture_logs() as logs:
#             try:
#                 function(*args, **kwargs)
#             except Exception:  # pragma: no cover
#                 if logs:
#                     print(f'{len(logs)} errors logged:', file=sys.stderr)
#                     for message in logs:
#                         print(message, file=sys.stderr)
#                 raise
#             else:
#                 if logs:  # pragma: no cover
#                     for message in logs:
#                         print(message, file=sys.stderr)
#                     raise AssertionError(f'{len(logs)} errors logged')
#     return wrapper
# 
# def render_pages(html_content):
#     """Lay out a document and return a list of PageBox objects."""
#     return [
#         page._page_box for page in
#         FakeHTML(string=html_content, base_url=BASE_URL).render().pages]


# Path: tests/layout/test_block.py
import pytest
from weasyprint.formatting_structure import boxes
from ..testing_utils import assert_no_logs, render_pages


@pytest.mark.parametrize('margin_1, margin_2, result', COLLAPSING)
def test_vertical_space_4(margin_1, margin_2, result):
    # Not siblings, second is doubly nested
    page, = render_pages('''
      <style>
        p { font: 20px/1 serif } /* block height == 20px */
        #p1 { margin-bottom: %s }
        #p2 { margin-top: %s }
      </style>
      <p id=p1>Lorem ipsum
      <div>
        <div>
            <p id=p2>dolor sit amet
        </div>
      </div>
    ''' % (margin_1, margin_2))
    html, = page.children
    body, = html.children
    p1, div1 = body.children
    div2, = div1.children
    p2, = div2.children
    p1_bottom = p1.content_box_y() + p1.height
    p2_top = p2.content_box_y()
    assert p2_top - p1_bottom == result


@pytest.mark.parametrize('margin_1, margin_2, result', COLLAPSING)
def test_vertical_space_5(margin_1, margin_2, result):
    # Collapsing with children

    page, = render_pages('''