File: test_common.py

package info (click to toggle)
weasyprint 62.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,964 kB
  • sloc: python: 54,652; makefile: 12
file content (206 lines) | stat: -rw-r--r-- 6,741 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
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 (  # isort:skip
    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='''
      <style>
        p:nth-child(1) { color: lime }
        body p:nth-child(2) { color: red }

        p:nth-child(3) { color: lime !important }
        body p:nth-child(3) { color: red }

        body p:nth-child(5) { color: lime }
        p:nth-child(5) { color: red }

        p:nth-child(6) { color: red }
        p:nth-child(6) { color: lime }
      </style>
      <p></p>
      <p></p>
      <p></p>
      <p></p>
      <p></p>
      <p></p>
    ''')
    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='''
      <style>@font-face {
        src: url(weasyprint.otf); font-family: weasyprint
      }</style>
      <body style="font: 10px weasyprint">
      <p style="margin-left: %s"></p>''' % 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='<p>a<span>b')
    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)