123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- import pytest
- from pandas.util import testing as tm
- from pandas.io.formats.css import CSSResolver, CSSWarning
- def assert_resolves(css, props, inherited=None):
- resolve = CSSResolver()
- actual = resolve(css, inherited=inherited)
- assert props == actual
- def assert_same_resolution(css1, css2, inherited=None):
- resolve = CSSResolver()
- resolved1 = resolve(css1, inherited=inherited)
- resolved2 = resolve(css2, inherited=inherited)
- assert resolved1 == resolved2
- @pytest.mark.parametrize('name,norm,abnorm', [
- ('whitespace', 'hello: world; foo: bar',
- ' \t hello \t :\n world \n ; \n foo: \tbar\n\n'),
- ('case', 'hello: world; foo: bar', 'Hello: WORLD; foO: bar'),
- ('empty-decl', 'hello: world; foo: bar',
- '; hello: world;; foo: bar;\n; ;'),
- ('empty-list', '', ';'),
- ])
- def test_css_parse_normalisation(name, norm, abnorm):
- assert_same_resolution(norm, abnorm)
- @pytest.mark.parametrize(
- 'invalid_css,remainder', [
- # No colon
- ('hello-world', ''),
- ('border-style: solid; hello-world', 'border-style: solid'),
- ('border-style: solid; hello-world; font-weight: bold',
- 'border-style: solid; font-weight: bold'),
- # Unclosed string fail
- # Invalid size
- ('font-size: blah', 'font-size: 1em'),
- ('font-size: 1a2b', 'font-size: 1em'),
- ('font-size: 1e5pt', 'font-size: 1em'),
- ('font-size: 1+6pt', 'font-size: 1em'),
- ('font-size: 1unknownunit', 'font-size: 1em'),
- ('font-size: 10', 'font-size: 1em'),
- ('font-size: 10 pt', 'font-size: 1em'),
- ])
- def test_css_parse_invalid(invalid_css, remainder):
- with tm.assert_produces_warning(CSSWarning):
- assert_same_resolution(invalid_css, remainder)
- # TODO: we should be checking that in other cases no warnings are raised
- @pytest.mark.parametrize(
- 'shorthand,expansions',
- [('margin', ['margin-top', 'margin-right',
- 'margin-bottom', 'margin-left']),
- ('padding', ['padding-top', 'padding-right',
- 'padding-bottom', 'padding-left']),
- ('border-width', ['border-top-width', 'border-right-width',
- 'border-bottom-width', 'border-left-width']),
- ('border-color', ['border-top-color', 'border-right-color',
- 'border-bottom-color', 'border-left-color']),
- ('border-style', ['border-top-style', 'border-right-style',
- 'border-bottom-style', 'border-left-style']),
- ])
- def test_css_side_shorthands(shorthand, expansions):
- top, right, bottom, left = expansions
- assert_resolves('{shorthand}: 1pt'.format(shorthand=shorthand),
- {top: '1pt', right: '1pt',
- bottom: '1pt', left: '1pt'})
- assert_resolves('{shorthand}: 1pt 4pt'.format(shorthand=shorthand),
- {top: '1pt', right: '4pt',
- bottom: '1pt', left: '4pt'})
- assert_resolves('{shorthand}: 1pt 4pt 2pt'.format(shorthand=shorthand),
- {top: '1pt', right: '4pt',
- bottom: '2pt', left: '4pt'})
- assert_resolves('{shorthand}: 1pt 4pt 2pt 0pt'.format(shorthand=shorthand),
- {top: '1pt', right: '4pt',
- bottom: '2pt', left: '0pt'})
- with tm.assert_produces_warning(CSSWarning):
- assert_resolves(
- '{shorthand}: 1pt 1pt 1pt 1pt 1pt'.format(shorthand=shorthand), {})
- @pytest.mark.parametrize('style,inherited,equiv', [
- ('margin: 1px; margin: 2px', '',
- 'margin: 2px'),
- ('margin: 1px', 'margin: 2px',
- 'margin: 1px'),
- ('margin: 1px; margin: inherit', 'margin: 2px',
- 'margin: 2px'),
- ('margin: 1px; margin-top: 2px', '',
- 'margin-left: 1px; margin-right: 1px; ' +
- 'margin-bottom: 1px; margin-top: 2px'),
- ('margin-top: 2px', 'margin: 1px',
- 'margin: 1px; margin-top: 2px'),
- ('margin: 1px', 'margin-top: 2px',
- 'margin: 1px'),
- ('margin: 1px; margin-top: inherit', 'margin: 2px',
- 'margin: 1px; margin-top: 2px'),
- ])
- def test_css_precedence(style, inherited, equiv):
- resolve = CSSResolver()
- inherited_props = resolve(inherited)
- style_props = resolve(style, inherited=inherited_props)
- equiv_props = resolve(equiv)
- assert style_props == equiv_props
- @pytest.mark.parametrize('style,equiv', [
- ('margin: 1px; margin-top: inherit',
- 'margin-bottom: 1px; margin-right: 1px; margin-left: 1px'),
- ('margin-top: inherit', ''),
- ('margin-top: initial', ''),
- ])
- def test_css_none_absent(style, equiv):
- assert_same_resolution(style, equiv)
- @pytest.mark.parametrize('size,resolved', [
- ('xx-small', '6pt'),
- ('x-small', '{pt:f}pt'.format(pt=7.5)),
- ('small', '{pt:f}pt'.format(pt=9.6)),
- ('medium', '12pt'),
- ('large', '{pt:f}pt'.format(pt=13.5)),
- ('x-large', '18pt'),
- ('xx-large', '24pt'),
- ('8px', '6pt'),
- ('1.25pc', '15pt'),
- ('.25in', '18pt'),
- ('02.54cm', '72pt'),
- ('25.4mm', '72pt'),
- ('101.6q', '72pt'),
- ('101.6q', '72pt'),
- ])
- @pytest.mark.parametrize('relative_to', # invariant to inherited size
- [None, '16pt'])
- def test_css_absolute_font_size(size, relative_to, resolved):
- if relative_to is None:
- inherited = None
- else:
- inherited = {'font-size': relative_to}
- assert_resolves('font-size: {size}'.format(size=size),
- {'font-size': resolved}, inherited=inherited)
- @pytest.mark.parametrize('size,relative_to,resolved', [
- ('1em', None, '12pt'),
- ('1.0em', None, '12pt'),
- ('1.25em', None, '15pt'),
- ('1em', '16pt', '16pt'),
- ('1.0em', '16pt', '16pt'),
- ('1.25em', '16pt', '20pt'),
- ('1rem', '16pt', '12pt'),
- ('1.0rem', '16pt', '12pt'),
- ('1.25rem', '16pt', '15pt'),
- ('100%', None, '12pt'),
- ('125%', None, '15pt'),
- ('100%', '16pt', '16pt'),
- ('125%', '16pt', '20pt'),
- ('2ex', None, '12pt'),
- ('2.0ex', None, '12pt'),
- ('2.50ex', None, '15pt'),
- ('inherit', '16pt', '16pt'),
- ('smaller', None, '10pt'),
- ('smaller', '18pt', '15pt'),
- ('larger', None, '{pt:f}pt'.format(pt=14.4)),
- ('larger', '15pt', '18pt'),
- ])
- def test_css_relative_font_size(size, relative_to, resolved):
- if relative_to is None:
- inherited = None
- else:
- inherited = {'font-size': relative_to}
- assert_resolves('font-size: {size}'.format(size=size),
- {'font-size': resolved}, inherited=inherited)
|