diff --git a/tests/css/__init__.py b/tests/css/__init__.py new file mode 100644 index 0000000000..66739c4083 --- /dev/null +++ b/tests/css/__init__.py @@ -0,0 +1 @@ +"""Test CSS features.""" diff --git a/tests/css/test_common.py b/tests/css/test_common.py new file mode 100644 index 0000000000..0fec4a5a8e --- /dev/null +++ b/tests/css/test_common.py @@ -0,0 +1,206 @@ +"""Test the CSS parsing, cascade, inherited and computed values.""" + + +import pytest +from weasyprint import CSS, default_url_fetcher +from weasyprint.css import find_stylesheets, get_all_computed_styles +from weasyprint.urls import path2url + +from ..testing_utils import ( + BASE_URL, FakeHTML, assert_no_logs, capture_logs, resource_path) + + +@assert_no_logs +def test_find_stylesheets(): + html = FakeHTML(resource_path('doc1.html')) + + sheets = list(find_stylesheets( + html.wrapper_element, 'print', default_url_fetcher, html.base_url, + font_config=None, counter_style=None, page_rules=None)) + assert len(sheets) == 2 + # Also test that stylesheets are in tree order. + sheet_names = [ + sheet.base_url.rsplit('/', 1)[-1].rsplit(',', 1)[-1] + for sheet in sheets] + assert sheet_names == ['a%7Bcolor%3AcurrentColor%7D', 'doc1.html'] + + rules = [] + for sheet in sheets: + for sheet_rules in sheet.matcher.lower_local_name_selectors.values(): + for rule in sheet_rules: + rules.append(rule) + for rule in sheet.page_rules: + rules.append(rule) + assert len(rules) == 10 + + # TODO: Test that the values are correct too. + + +@assert_no_logs +def test_annotate_document(): + document = FakeHTML(resource_path('doc1.html')) + document._ua_stylesheets = ( + lambda *_, **__: [CSS(resource_path('mini_ua.css'))]) + style_for = get_all_computed_styles( + document, user_stylesheets=[CSS(resource_path('user.css'))]) + + # Element objects behave as lists of their children. + _head, body = document.etree_element + h1, p, ul, div = body + li_0, _li_1 = ul + a, = li_0 + span1, = div + span2, = span1 + + h1 = style_for(h1) + p = style_for(p) + ul = style_for(ul) + li_0 = style_for(li_0) + div = style_for(div) + after = style_for(a, 'after') + a = style_for(a) + span1 = style_for(span1) + span2 = style_for(span2) + + assert h1['background_image'] == ( + ('url', path2url(resource_path('logo_small.png'))),) + + assert h1['font_weight'] == 700 + assert h1['font_size'] == 40 # 2em + + # x-large * initial = 3/2 * 16 = 24 + assert p['margin_top'] == (24, 'px') + assert p['margin_right'] == (0, 'px') + assert p['margin_bottom'] == (24, 'px') + assert p['margin_left'] == (0, 'px') + assert p['background_color'] == 'currentColor' + + # 2em * 1.25ex = 2 * 20 * 1.25 * 0.8 = 40 + # 2.5ex * 1.25ex = 2.5 * 0.8 * 20 * 1.25 * 0.8 = 40 + # TODO: ex unit doesn't work with @font-face fonts, see computed_values.py + # assert ul['margin_top'] == (40, 'px') + # assert ul['margin_right'] == (40, 'px') + # assert ul['margin_bottom'] == (40, 'px') + # assert ul['margin_left'] == (40, 'px') + + assert ul['font_weight'] == 400 + # thick = 5px, 0.25 inches = 96*.25 = 24px + assert ul['border_top_width'] == 0 + assert ul['border_right_width'] == 5 + assert ul['border_bottom_width'] == 0 + assert ul['border_left_width'] == 24 + + assert li_0['font_weight'] == 700 + assert li_0['font_size'] == 8 # 6pt + assert li_0['margin_top'] == (16, 'px') # 2em + assert li_0['margin_right'] == (0, 'px') + assert li_0['margin_bottom'] == (16, 'px') + assert li_0['margin_left'] == (32, 'px') # 4em + + assert a['text_decoration_line'] == {'underline'} + assert a['font_weight'] == 900 + assert a['font_size'] == 24 # 300% of 8px + assert a['padding_top'] == (1, 'px') + assert a['padding_right'] == (2, 'px') + assert a['padding_bottom'] == (3, 'px') + assert a['padding_left'] == (4, 'px') + assert a['border_top_width'] == 42 + assert a['border_bottom_width'] == 42 + + assert a['color'] == (1, 0, 0, 1) + assert a['border_top_color'] == 'currentColor' + + assert div['font_size'] == 40 # 2 * 20px + assert span1['width'] == (160, 'px') # 10 * 16px (root default is 16px) + assert span1['height'] == (400, 'px') # 10 * (2 * 20px) + assert span2['font_size'] == 32 + + # The href attr should be as in the source, not made absolute. + assert after['content'] == ( + ('string', ' ['), ('string', 'home.html'), ('string', ']')) + assert after['background_color'] == (1, 0, 0, 1) + assert after['border_top_width'] == 42 + assert after['border_bottom_width'] == 3 + + # TODO: much more tests here: test that origin and selector precedence + # and inheritance are correct… + + +@assert_no_logs +def test_important(): + document = FakeHTML(string=''' + +

+

+

+

+

+

+ ''') + page, = document.render(stylesheets=[CSS(string=''' + body p:nth-child(1) { color: red } + p:nth-child(2) { color: lime !important } + + p:nth-child(4) { color: lime !important } + body p:nth-child(4) { color: red } + ''')]).pages + html, = page._page_box.children + body, = html.children + for paragraph in body.children: + assert paragraph.style['color'] == (0, 1, 0, 1) # lime (light green) + + +@assert_no_logs +@pytest.mark.parametrize('value, width', ( + ('96px', 96), + ('1in', 96), + ('72pt', 96), + ('6pc', 96), + ('2.54cm', 96), + ('25.4mm', 96), + ('101.6q', 96), + ('1.1em', 11), + ('1.1rem', 17.6), + # TODO: ch and ex units don't work with font-face, see computed_values.py. + # ('1.1ch', 11), + # ('1.5ex', 12), +)) +def test_units(value, width): + document = FakeHTML(base_url=BASE_URL, string=''' + + +

''' % value) + page, = document.render().pages + html, = page._page_box.children + body, = html.children + p, = body.children + assert p.margin_left == width + + +@pytest.mark.parametrize('media, width, warning', ( + ('@media screen { @page { size: 10px } }', 20, False), + ('@media print { @page { size: 10px } }', 10, False), + ('@media ("unknown content") { @page { size: 10px } }', 20, True), +)) +def test_media_queries(media, width, warning): + document = FakeHTML(string='

ab') + with capture_logs() as logs: + page, = document.render( + stylesheets=[CSS(string='@page{size:20px}%s' % media)]).pages + html, = page._page_box.children + assert html.width == width + assert (logs if warning else not logs) diff --git a/tests/test_counters.py b/tests/css/test_counters.py similarity index 93% rename from tests/test_counters.py rename to tests/css/test_counters.py index a6b8731811..ddf363e1cb 100644 --- a/tests/test_counters.py +++ b/tests/css/test_counters.py @@ -1,9 +1,11 @@ """Test CSS counters.""" import pytest -from weasyprint import HTML -from .testing_utils import assert_no_logs, assert_tree, parse_all, render_pages +from ..testing_utils import ( + FakeHTML, assert_no_logs, assert_tree, parse_all, render_pages) + +RENDER = FakeHTML(string='')._ua_counter_style()[0].render_value @assert_no_logs @@ -237,7 +239,7 @@ def test_counters_8(): @pytest.mark.xfail @assert_no_logs def test_counters_9(): - document = HTML(string=''' + page, = render_pages('''

  1. @@ -248,8 +250,7 @@ def test_counters_9():
- ''').render() - page, = document.pages + ''') html, = page._page_box.children body, = html.children ol1, = body.children @@ -328,8 +329,7 @@ def test_counter_styles_2(): @assert_no_logs def test_counter_styles_3(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'decimal-leading-zero') for value in [ + assert [RENDER(value, 'decimal-leading-zero') for value in [ -1986, -1985, -11, -10, -9, -8, -1, 0, 1, 2, @@ -344,8 +344,7 @@ def test_counter_styles_3(): @assert_no_logs def test_counter_styles_4(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'lower-roman') for value in [ + assert [RENDER(value, 'lower-roman') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 49, 50, @@ -361,8 +360,7 @@ def test_counter_styles_4(): @assert_no_logs def test_counter_styles_5(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'upper-roman') for value in [ + assert [RENDER(value, 'upper-roman') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 49, 50, @@ -378,8 +376,7 @@ def test_counter_styles_5(): @assert_no_logs def test_counter_styles_6(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'lower-alpha') for value in [ + assert [RENDER(value, 'lower-alpha') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29, @@ -391,8 +388,7 @@ def test_counter_styles_6(): @assert_no_logs def test_counter_styles_7(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'upper-alpha') for value in [ + assert [RENDER(value, 'upper-alpha') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29, @@ -404,8 +400,7 @@ def test_counter_styles_7(): @assert_no_logs def test_counter_styles_8(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'lower-latin') for value in [ + assert [RENDER(value, 'lower-latin') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29, @@ -417,8 +412,7 @@ def test_counter_styles_8(): @assert_no_logs def test_counter_styles_9(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'upper-latin') for value in [ + assert [RENDER(value, 'upper-latin') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 25, 26, 27, 28, 29, @@ -430,8 +424,7 @@ def test_counter_styles_9(): @assert_no_logs def test_counter_styles_10(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'georgian') for value in [ + assert [RENDER(value, 'georgian') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20, 30, 40, 50, 60, 70, 80, 90, 100, @@ -450,8 +443,7 @@ def test_counter_styles_10(): @assert_no_logs def test_counter_styles_11(): - render = HTML(string='')._ua_counter_style()[0].render_value - assert [render(value, 'armenian') for value in [ + assert [RENDER(value, 'armenian') for value in [ -1986, -1985, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20, 30, 40, 50, 60, 70, 80, 90, 100, diff --git a/tests/test_css_descriptors.py b/tests/css/test_descriptors.py similarity index 99% rename from tests/test_css_descriptors.py rename to tests/css/test_descriptors.py index 18544f1461..0ee38b84ca 100644 --- a/tests/test_css_descriptors.py +++ b/tests/css/test_descriptors.py @@ -5,7 +5,7 @@ from weasyprint.css import preprocess_stylesheet from weasyprint.css.validation.descriptors import preprocess_descriptors -from .testing_utils import assert_no_logs, capture_logs +from ..testing_utils import assert_no_logs, capture_logs @assert_no_logs diff --git a/tests/css/test_errors.py b/tests/css/test_errors.py new file mode 100644 index 0000000000..f29115d3d6 --- /dev/null +++ b/tests/css/test_errors.py @@ -0,0 +1,48 @@ +"""Test CSS errors and warnings.""" + +import pytest +from weasyprint import CSS + +from ..testing_utils import assert_no_logs, capture_logs, render_pages + + +@assert_no_logs +@pytest.mark.parametrize('source, messages', ( + (':lipsum { margin: 2cm', ['WARNING: Invalid or unsupported selector']), + ('::lipsum { margin: 2cm', ['WARNING: Invalid or unsupported selector']), + ('foo { margin-color: red', ['WARNING: Ignored', 'unknown property']), + ('foo { margin-top: red', ['WARNING: Ignored', 'invalid value']), + ('@import "relative-uri.css"', + ['ERROR: Relative URI reference without a base URI']), + ('@import "invalid-protocol://absolute-URL"', + ['ERROR: Failed to load stylesheet at']), +)) +def test_warnings(source, messages): + with capture_logs() as logs: + CSS(string=source) + assert len(logs) == 1, source + for message in messages: + assert message in logs[0] + + +@assert_no_logs +def test_warnings_stylesheet(): + with capture_logs() as logs: + render_pages('') + assert len(logs) == 1 + assert 'ERROR: Failed to load stylesheet at' in logs[0] + + +@assert_no_logs +@pytest.mark.parametrize('style', ( + ' +

+ ''') + html, = page.children + body, = html.children + div, = body.children + section, = div.children + paragraph, = section.children + assert html.style['font_size'] == 10 + assert div.style['font_size'] == 20 + # 140% of 10px = 14px is inherited from html + assert strut_layout(div.style)[0] == 14 + assert div.style['vertical_align'] == 7 # 50 % of 14px + + assert paragraph.style['font_size'] == 20 + # 1.4 is inherited from p, 1.4 * 20px on em = 28px + assert strut_layout(paragraph.style)[0] == 28 + assert paragraph.style['vertical_align'] == 14 # 50% of 28px diff --git a/tests/css/test_nesting.py b/tests/css/test_nesting.py new file mode 100644 index 0000000000..f3b4630cd6 --- /dev/null +++ b/tests/css/test_nesting.py @@ -0,0 +1,27 @@ +"""Test CSS nesting.""" + +import pytest + +from ..testing_utils import assert_no_logs, render_pages + + +@assert_no_logs +@pytest.mark.parametrize('style', ( + 'div { p { width: 10px } }', + 'p { div & { width: 10px } }', + 'p { width: 20px; div & { width: 10px } }', + 'p { div & { width: 10px } width: 20px }', + 'div { & { & { p { & { width: 10px } } } } }', + '@media print { div { p { width: 10px } } }', +)) +def test_nesting_block(style): + page, = render_pages(''' + +

+ ''' % style) + html, = page.children + body, = html.children + div, p = body.children + div_p, = div.children + assert div_p.width == 10 + assert p.width != 10 diff --git a/tests/css/test_pages.py b/tests/css/test_pages.py new file mode 100644 index 0000000000..82791cc41e --- /dev/null +++ b/tests/css/test_pages.py @@ -0,0 +1,165 @@ +"""Test CSS pages.""" + +import pytest +import tinycss2 +from weasyprint import CSS +from weasyprint.css import ( + PageType, get_all_computed_styles, parse_page_selectors) +from weasyprint.layout.page import set_page_type_computed_styles + +from ..testing_utils import ( + FakeHTML, assert_no_logs, render_pages, resource_path) + + +@assert_no_logs +def test_page(): + document = FakeHTML(resource_path('doc1.html')) + style_for = get_all_computed_styles( + document, user_stylesheets=[CSS(string=''' + html { color: red } + @page { margin: 10px } + @page :right { + color: blue; + margin-bottom: 12pt; + font-size: 20px; + @top-left { width: 10em } + @top-right { font-size: 10px} + } + ''')]) + + page_type = PageType( + side='left', first=True, blank=False, index=0, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type) + assert style['margin_top'] == (5, 'px') + assert style['margin_left'] == (10, 'px') + assert style['margin_bottom'] == (10, 'px') + assert style['color'] == (1, 0, 0, 1) # red, inherited from html + + page_type = PageType( + side='right', first=True, blank=False, index=0, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type) + assert style['margin_top'] == (5, 'px') + assert style['margin_left'] == (10, 'px') + assert style['margin_bottom'] == (16, 'px') + assert style['color'] == (0, 0, 1, 1) # blue + + page_type = PageType( + side='left', first=False, blank=False, index=1, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type) + assert style['margin_top'] == (10, 'px') + assert style['margin_left'] == (10, 'px') + assert style['margin_bottom'] == (10, 'px') + assert style['color'] == (1, 0, 0, 1) # red, inherited from html + + page_type = PageType( + side='right', first=False, blank=False, index=1, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type) + assert style['margin_top'] == (10, 'px') + assert style['margin_left'] == (10, 'px') + assert style['margin_bottom'] == (16, 'px') + assert style['color'] == (0, 0, 1, 1) # blue + + page_type = PageType( + side='left', first=True, blank=False, index=0, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type, '@top-left') + assert style is None + + page_type = PageType( + side='right', first=True, blank=False, index=0, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type, '@top-left') + assert style['font_size'] == 20 # inherited from @page + assert style['width'] == (200, 'px') + + page_type = PageType( + side='right', first=True, blank=False, index=0, name='') + set_page_type_computed_styles(page_type, document, style_for) + style = style_for(page_type, '@top-right') + assert style['font_size'] == 10 + + +@assert_no_logs +@pytest.mark.parametrize('style, selectors', ( + ('@page {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': None, 'specificity': [0, 0, 0]}]), + ('@page :left {}', [{ + 'side': 'left', 'blank': None, 'first': None, 'name': None, + 'index': None, 'specificity': [0, 0, 1]}]), + ('@page:first:left {}', [{ + 'side': 'left', 'blank': None, 'first': True, 'name': None, + 'index': None, 'specificity': [0, 1, 1]}]), + ('@page pagename {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': 'pagename', + 'index': None, 'specificity': [1, 0, 0]}]), + ('@page pagename:first:right:blank {}', [{ + 'side': 'right', 'blank': True, 'first': True, 'name': 'pagename', + 'index': None, 'specificity': [1, 2, 1]}]), + ('@page pagename, :first {}', [ + {'side': None, 'blank': None, 'first': None, 'name': 'pagename', + 'index': None, 'specificity': [1, 0, 0]}, + {'side': None, 'blank': None, 'first': True, 'name': None, + 'index': None, 'specificity': [0, 1, 0]}]), + ('@page :first:first {}', [{ + 'side': None, 'blank': None, 'first': True, 'name': None, + 'index': None, 'specificity': [0, 2, 0]}]), + ('@page :left:left {}', [{ + 'side': 'left', 'blank': None, 'first': None, 'name': None, + 'index': None, 'specificity': [0, 0, 2]}]), + ('@page :nth(2) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': (0, 2, None), 'specificity': [0, 1, 0]}]), + ('@page :nth(2n + 4) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': (2, 4, None), 'specificity': [0, 1, 0]}]), + ('@page :nth(3n) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': (3, 0, None), 'specificity': [0, 1, 0]}]), + ('@page :nth( n+2 ) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': (1, 2, None), 'specificity': [0, 1, 0]}]), + ('@page :nth(even) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': None, + 'index': (2, 0, None), 'specificity': [0, 1, 0]}]), + ('@page pagename:nth(2) {}', [{ + 'side': None, 'blank': None, 'first': None, 'name': 'pagename', + 'index': (0, 2, None), 'specificity': [1, 1, 0]}]), + ('@page page page {}', None), + ('@page :left page {}', None), + ('@page :left, {}', None), + ('@page , {}', None), + ('@page :left, test, {}', None), + ('@page :wrong {}', None), + ('@page :left:wrong {}', None), + ('@page :left:right {}', None), +)) +def test_page_selectors(style, selectors): + at_rule, = tinycss2.parse_stylesheet(style) + assert parse_page_selectors(at_rule) == selectors + + +@assert_no_logs +def test_named_pages(): + page, = render_pages(''' + +

a

+ ''') + html, = page.children + body, = html.children + div, = body.children + p, = div.children + span, = p.children + assert html.style['page'] == '' + assert body.style['page'] == '' + assert div.style['page'] == '' + assert p.style['page'] == 'NARRow' + assert span.style['page'] == 'NARRow' diff --git a/tests/css/test_shorthands.py b/tests/css/test_shorthands.py new file mode 100644 index 0000000000..19f594bb14 --- /dev/null +++ b/tests/css/test_shorthands.py @@ -0,0 +1,29 @@ +"""Test CSS shorthands.""" + +from weasyprint import CSS + +from ..testing_utils import assert_no_logs, resource_path + + +@assert_no_logs +def test_expand_shorthands(): + sheet = CSS(resource_path('sheet2.css')) + assert list(sheet.matcher.lower_local_name_selectors) == ['li'] + + rules = sheet.matcher.lower_local_name_selectors['li'][0][4] + assert rules[0][0] == 'margin_bottom' + assert rules[0][1] == (3, 'em') + assert rules[1][0] == 'margin_top' + assert rules[1][1] == (2, 'em') + assert rules[2][0] == 'margin_right' + assert rules[2][1] == (0, None) + assert rules[3][0] == 'margin_bottom' + assert rules[3][1] == (2, 'em') + assert rules[4][0] == 'margin_left' + assert rules[4][1] == (0, None) + assert rules[5][0] == 'margin_left' + assert rules[5][1] == (4, 'em') + + # TODO: test that the values are correct too. + + diff --git a/tests/test_target.py b/tests/css/test_target.py similarity index 88% rename from tests/test_target.py rename to tests/css/test_target.py index 65db410a6b..659d68e901 100644 --- a/tests/test_target.py +++ b/tests/css/test_target.py @@ -1,11 +1,11 @@ """Test the CSS cross references using target-*() functions.""" -from .testing_utils import FakeHTML, assert_no_logs +from ..testing_utils import assert_no_logs, render_pages @assert_no_logs def test_target_counter(): - document = FakeHTML(string=''' + page, = render_pages(''' -

- ''') - page, = document.render().pages - html, = page._page_box.children - body, = html.children - div, = body.children - section, = div.children - paragraph, = section.children - assert html.style['font_size'] == 10 - assert div.style['font_size'] == 20 - # 140% of 10px = 14px is inherited from html - assert strut_layout(div.style)[0] == 14 - assert div.style['vertical_align'] == 7 # 50 % of 14px - - assert paragraph.style['font_size'] == 20 - # 1.4 is inherited from p, 1.4 * 20px on em = 28px - assert strut_layout(paragraph.style)[0] == 28 - assert paragraph.style['vertical_align'] == 14 # 50% of 28px - - -@assert_no_logs -def test_important(): - document = FakeHTML(string=''' - -

-

-

-

-

-

- ''') - page, = document.render(stylesheets=[CSS(string=''' - body p:nth-child(1) { color: red } - p:nth-child(2) { color: lime !important } - - p:nth-child(4) { color: lime !important } - body p:nth-child(4) { color: red } - ''')]).pages - html, = page._page_box.children - body, = html.children - for paragraph in body.children: - assert paragraph.style['color'] == (0, 1, 0, 1) # lime (light green) - - -@assert_no_logs -def test_named_pages(): - document = FakeHTML(string=''' - -

a

- ''') - page, = document.render().pages - html, = page._page_box.children - body, = html.children - div, = body.children - p, = div.children - span, = p.children - assert html.style['page'] == '' - assert body.style['page'] == '' - assert div.style['page'] == '' - assert p.style['page'] == 'NARRow' - assert span.style['page'] == 'NARRow' - - -@assert_no_logs -@pytest.mark.parametrize('value, width', ( - ('96px', 96), - ('1in', 96), - ('72pt', 96), - ('6pc', 96), - ('2.54cm', 96), - ('25.4mm', 96), - ('101.6q', 96), - ('1.1em', 11), - ('1.1rem', 17.6), - # TODO: ch and ex units don't work with font-face, see computed_values.py - # ('1.1ch', 11), - # ('1.5ex', 12), -)) -def test_units(value, width): - document = FakeHTML(base_url=BASE_URL, string=''' - - -

''' % value) - page, = document.render().pages - html, = page._page_box.children - body, = html.children - p, = body.children - assert p.margin_left == width - - -@assert_no_logs -@pytest.mark.parametrize('parent_css, parent_size, child_css, child_size', ( - ('10px', 10, '10px', 10), - ('x-small', 12, 'xx-large', 32), - ('x-large', 24, '2em', 48), - ('1em', 16, '1em', 16), - ('1em', 16, 'larger', 6 / 5 * 16), - ('medium', 16, 'larger', 6 / 5 * 16), - ('x-large', 24, 'larger', 32), - ('xx-large', 32, 'larger', 1.2 * 32), - ('1px', 1, 'larger', 3 / 5 * 16), - ('28px', 28, 'larger', 32), - ('100px', 100, 'larger', 120), - ('xx-small', 3 / 5 * 16, 'larger', 12), - ('1em', 16, 'smaller', 8 / 9 * 16), - ('medium', 16, 'smaller', 8 / 9 * 16), - ('x-large', 24, 'smaller', 6 / 5 * 16), - ('xx-large', 32, 'smaller', 24), - ('xx-small', 3 / 5 * 16, 'smaller', 0.8 * 3 / 5 * 16), - ('1px', 1, 'smaller', 0.8), - ('28px', 28, 'smaller', 24), - ('100px', 100, 'smaller', 32), -)) -def test_font_size(parent_css, parent_size, child_css, child_size): - document = FakeHTML(string='

ab') - style_for = get_all_computed_styles(document, user_stylesheets=[CSS( - string='p{font-size:%s}span{font-size:%s}' % (parent_css, child_css))]) - - _head, body = document.etree_element - p, = body - span, = p - assert isclose(style_for(p)['font_size'], parent_size) - assert isclose(style_for(span)['font_size'], child_size) - - -@pytest.mark.parametrize('media, width, warning', ( - ('@media screen { @page { size: 10px } }', 20, False), - ('@media print { @page { size: 10px } }', 10, False), - ('@media ("unknown content") { @page { size: 10px } }', 20, True), -)) -def test_media_queries(media, width, warning): - document = FakeHTML(string='

ab') - with capture_logs() as logs: - page, = document.render( - stylesheets=[CSS(string='@page{size:20px}%s' % media)]).pages - html, = page._page_box.children - assert html.width == width - assert (logs if warning else not logs)