diff --git a/dict2css/__init__.py b/dict2css/__init__.py index 3ad1289..13c3918 100644 --- a/dict2css/__init__.py +++ b/dict2css/__init__.py @@ -3,9 +3,6 @@ # __init__.py """ A μ-library for constructing cascasing style sheets from Python dictionaries. - -.. latex:vspace:: 10px -.. seealso:: `css-parser `_, which this library builds upon. """ # # Copyright © 2020-2021 Dominic Davis-Foster @@ -31,25 +28,21 @@ # stdlib from io import TextIOBase -from typing import IO, Any, Dict, Mapping, MutableMapping, Sequence, Union, cast +from typing import IO, Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Sequence, Union # 3rd party +import tinycss2 # type: ignore[import-untyped] +import tinycss2.ast # type: ignore[import-untyped] from domdf_python_tools.paths import PathPlus from domdf_python_tools.typing import PathLike from domdf_python_tools.words import TAB -try: - # 3rd party - import css_parser # type: ignore -except ImportError: # pragma: no cover - import cssutils as css_parser # type: ignore - # this package from dict2css.helpers import em, px, rem # noqa: F401 from dict2css.serializer import CSSSerializer __author__: str = "Dominic Davis-Foster" -__copyright__: str = "2020-2021 Dominic Davis-Foster" +__copyright__: str = "2020-2026 Dominic Davis-Foster" __license__: str = "MIT License" __version__: str = "0.4.0" __email__: str = "dominic@davis-foster.co.uk" @@ -61,10 +54,10 @@ "dump", "loads", "load", - "StyleSheet", - "make_style", ] +# TODO: allow int indent like json.dumps etc. + IMPORTANT = "important" """ The string ``'important'``. @@ -73,11 +66,11 @@ """ # Property = Union[Tuple[Union[str, int, None], str], str, int, None] -Property = Union[Sequence, str, int, None] +Property = Union[Sequence, str, int, float, None] Style = Mapping[str, Property] """ -Type annotation representing a style for :func:`~.make_style` and :func:`~.dumps`. +Type annotation representing a style for :func:`~.dumps` and :func:`~.dump`. The keys are CSS properties. @@ -93,9 +86,11 @@ def dumps( styles: Mapping[str, Union[Style, Mapping]], *, indent: str = TAB, - trailing_semicolon: bool = False, + trailing_semicolon: Optional[bool] = None, indent_closing_brace: bool = False, minify: bool = False, + sort_keys: bool = False, + check_circular: bool = True, ) -> str: r""" Construct a cascading style sheet from a dictionary. @@ -139,10 +134,13 @@ def dumps( :param trailing_semicolon: Whether to add a semicolon to the end of the final property. :param indent_closing_brace: :param minify: Minify the CSS. Overrides all other options. + :param sort_keys: Sort dictionary keys alphabetically. + :param check_circular: Check for circular references. :return: The style sheet as a string. .. versionchanged:: 0.2.0 Added support for media at-rules. + .. versionchanged:: 0.5.0 New implementation. Output may differ slightly from previous css-parser based one. """ serializer = CSSSerializer( @@ -150,27 +148,16 @@ def dumps( trailing_semicolon=trailing_semicolon, indent_closing_brace=indent_closing_brace, minify=minify, + sort_keys=sort_keys, + check_circular=check_circular, ) - stylesheet: str = '' - - with serializer.use(): - sheet = StyleSheet() - - for selector, style in styles.items(): - if selector.startswith("@media"): - sheet.add_media_styles(selector.split("@media")[1].strip(), cast(Mapping[str, Style], style)) - elif selector.startswith('@'): - raise NotImplementedError("Only @media at-rules are supported at this time.") - else: - sheet.add_style(selector, cast(Style, style)) + css = serializer.encode(styles).rstrip() - stylesheet = sheet.tostring() - - if not serializer.minify: - stylesheet = stylesheet.replace('}', "}\n") - - return stylesheet + if css: + return css + '\n' + else: + return '' def dump( @@ -178,9 +165,11 @@ def dump( fp: Union[PathLike, IO], *, indent: str = TAB, - trailing_semicolon: bool = False, + trailing_semicolon: Optional[bool] = None, indent_closing_brace: bool = False, minify: bool = False, + sort_keys: bool = False, + check_circular: bool = True, ) -> None: r""" Construct a style sheet from a dictionary and write it to ``fp``. @@ -225,12 +214,16 @@ def dump( :param trailing_semicolon: Whether to add a semicolon to the end of the final property. :param indent_closing_brace: :param minify: Minify the CSS. Overrides all other options. + :param sort_keys: Sort dictionary keys alphabetically. + :param check_circular: Check for circular references. .. versionchanged:: 0.2.0 * ``fp`` now accepts :py:obj:`domdf_python_tools.typing.PathLike` objects, representing the path of a file to write to. * Added support for media at-rules. + + .. versionchanged:: 0.5.0 New implementation. Output may differ slightly from previous css-parser based one. """ css = dumps( @@ -238,6 +231,8 @@ def dump( indent=indent, trailing_semicolon=trailing_semicolon, indent_closing_brace=indent_closing_brace, + sort_keys=sort_keys, + check_circular=check_circular, minify=minify, ) @@ -252,43 +247,44 @@ def loads(styles: str) -> MutableMapping[str, MutableMapping[str, Any]]: Parse a style sheet and return its dictionary representation. .. versionadded:: 0.2.0 + .. versionchanged:: 0.5.0 New implementation. Output may differ slightly from previous css-parser based one. :param styles: :return: The style sheet as a dictionary. + + .. latex:clearpage:: """ - parser = css_parser.CSSParser(validate=False) - stylesheet: css_parser.css.CSSStyleSheet = parser.parseString(styles) + stylesheet = tinycss2.parse_blocks_contents(styles, skip_comments=True, skip_whitespace=True) styles_dict: MutableMapping[str, MutableMapping[str, Any]] = {} - def parse_style(style: css_parser.css.CSSStyleDeclaration) -> MutableMapping[str, Property]: + def parse_style(style: List[tinycss2.ast.Node]) -> MutableMapping[str, Property]: style_dict: Dict[str, Property] = {} - prop: css_parser.css.Property - for prop in style.children(): - if prop.priority: - style_dict[prop.name] = (prop.value, prop.priority) + prop: Union[tinycss2.ast.ParseError, tinycss2.ast.Declaration] + for prop in tinycss2.parse_declaration_list(style, skip_comments=True, skip_whitespace=True): + if isinstance(prop, tinycss2.ast.ParseError): + raise ValueError(prop) + + if prop.important: + style_dict[prop.name.strip()] = (_serialize(prop.value), IMPORTANT) else: - style_dict[prop.name] = prop.value + style_dict[prop.name.strip()] = _serialize(prop.value) return style_dict - rule: css_parser.css.CSSRule - for rule in stylesheet.cssRules: - if isinstance(rule, css_parser.css.CSSStyleRule): - styles_dict[rule.selectorText] = parse_style(rule.style) - - elif isinstance(rule, css_parser.css.CSSMediaRule): - styles_dict[f"@media {rule.media.mediaText}"] = {} + rule: tinycss2.ast.Node + for rule in stylesheet: + if isinstance(rule, tinycss2.ast.QualifiedRule): + styles_dict[_serialize(rule.prelude)] = parse_style(rule.content) - for child in rule.cssRules: - styles_dict[f"@media {rule.media.mediaText}"][child.selectorText] = parse_style(child.style) + elif isinstance(rule, tinycss2.ast.AtRule): + at_rule_styles = styles_dict[f"@{rule.at_keyword} {_serialize(rule.prelude)}"] = {} - elif isinstance(rule, (css_parser.css.CSSComment)): # pragma: no cover - # Ignore these classes - pass + for child in tinycss2.parse_blocks_contents(rule.content, skip_comments=True, skip_whitespace=True): + at_rule_styles[_serialize(child.prelude)] = parse_style(child.content) else: raise NotImplementedError(rule) @@ -296,11 +292,16 @@ def parse_style(style: css_parser.css.CSSStyleDeclaration) -> MutableMapping[str return styles_dict +def _serialize(nodes: Iterable[tinycss2.ast.Node]) -> str: + return tinycss2.serialize(nodes).strip() + + def load(fp: Union[PathLike, IO]) -> MutableMapping[str, MutableMapping[str, Any]]: r""" Parse a cascading style sheet from the given file and return its dictionary representation. .. versionadded:: 0.2.0 + .. versionchanged:: 0.5.0 New implementation. Output may differ slightly from previous css-parser based one. :param fp: An open file handle, or the filename of a file to write to. @@ -313,93 +314,3 @@ def load(fp: Union[PathLike, IO]) -> MutableMapping[str, MutableMapping[str, Any styles = PathPlus(fp).read_text() return loads(styles) - - -class StyleSheet(css_parser.css.CSSStyleSheet): - r""" - Represents a CSS style sheet. - - .. raw:: latex - - \nopagebreak - - .. autosummary-widths:: 7/16 - - """ - - def __init__(self): - super().__init__(validating=False) - - def add(self, rule: css_parser.css.CSSRule) -> int: - """ - Add the ``rule`` to the style sheet. - - :param rule: - :type rule: :class:`css_parser.css.CSSRule` - """ - - return super().add(rule) - - def add_style( - self, - selector: str, - styles: Style, - ) -> None: - """ - Add a style to the style sheet. - - :param selector: - :param styles: - """ - - self.add(make_style(selector, styles)) - - def add_media_styles( - self, - media_query: str, - styles: Mapping[str, Style], - ) -> None: - """ - Add a set of styles for a media query to the style sheet. - - .. versionadded:: 0.2.0 - - :param media_query: - :param styles: - """ - - media = css_parser.css.CSSMediaRule(media_query) - - for selector, style in styles.items(): - media.add(make_style(selector, style)) - - self.add(media) - - def tostring(self) -> str: - """ - Returns the style sheet as a string. - """ - - return self.cssText.decode("UTF-8") - - -def make_style(selector: str, styles: Style) -> css_parser.css.CSSStyleRule: - """ - Create a CSS Style Rule from a dictionary. - - :param selector: - :param styles: - - :rtype: :class:`css_parser.css.CSSStyleRule` - """ - - style = css_parser.css.CSSStyleDeclaration() - style.validating = False - - for name, properties in styles.items(): - if isinstance(properties, Sequence) and not isinstance(properties, str): - style[name] = tuple(str(x) for x in properties) - else: - style[name] = str(properties) - - return css_parser.css.CSSStyleRule(selectorText=selector, style=style) diff --git a/dict2css/serializer.py b/dict2css/serializer.py index d904228..6169b32 100644 --- a/dict2css/serializer.py +++ b/dict2css/serializer.py @@ -9,6 +9,9 @@ # # Copyright © 2021 Dominic Davis-Foster # +# Adapted from https://github.com/austinyu/ujson5 +# Copyright (c) 2025 Sir Austin +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights @@ -29,25 +32,47 @@ # # stdlib +import re from contextlib import contextmanager -from typing import Iterator +from typing import Any, Callable, Dict, Iterable, Iterator, Mapping, Optional, Union # 3rd party from domdf_python_tools.words import TAB -try: - # 3rd party - import css_parser # type: ignore -except ImportError: # pragma: no cover - # 3rd party - import cssutils as css_parser # type: ignore - __all__ = ["CSSSerializer"] +#: Python objects that can be serialized to CSS +Serializable = Union[dict, list, tuple, int, float, str, bool, None] + +#: A callable that takes in an object that is not serializable and returns a serializable object +DefaultInterface = Union[ + Callable[[Any], dict], + Callable[[Any], list], + Callable[[Any], tuple], + Callable[[Any], int], + Callable[[Any], float], + Callable[[Any], str], + Callable[[Any], bool], + Callable[[Any], Serializable] + ] -class CSSSerializer(css_parser.CSSSerializer): +ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') +ESCAPE_DCT = { + '\\': "\\\\", + '"': '\\"', + '\x08': "\\b", + '\x0c': "\\f", + '\n': "\\n", + '\r': "\\r", + '\t': "\\t", + } +for i in range(0x20): + ESCAPE_DCT.setdefault(chr(i), f"\\u{i:04x}") + + +class CSSSerializer: r""" - Serializes a :class:`~.StyleSheet` and its parts. + Serializes a dictionary to CSS. This controls the formatting of the style sheet. @@ -55,57 +80,308 @@ class CSSSerializer(css_parser.CSSSerializer): :param trailing_semicolon: Whether to add a semicolon to the end of the final property. :param indent_closing_brace: :param minify: Minify the CSS. Overrides all other options. + :param sort_keys: Sort dictionary keys alphabetically. + :param check_circular: Check for circular references. + + .. versionchanged:: 0.5.0 New implementation. Output may differ slightly from previous css-parser based one. - .. autosummary-widths:: 5/16 + .. autosummary-widths:: 1/4 """ def __init__( self, *, indent: str = TAB, - trailing_semicolon: bool = False, + trailing_semicolon: Optional[bool] = None, + indent_closing_brace: bool = False, + minify: bool = False, + sort_keys: bool = False, + check_circular: bool = True, # default: Optional[DefaultInterface] = None, + ) -> None: + self._set_options( + indent=indent, + trailing_semicolon=trailing_semicolon, + indent_closing_brace=indent_closing_brace, + minify=minify, + sort_keys=sort_keys, + ) + + if check_circular: + self._markers: Optional[Dict[int, Any]] = {} + else: + self._markers = None + + # TODO self._default: Optional[DefaultInterface] = default + self._default: Optional[DefaultInterface] = None + + def _set_options( + self, + indent: str = TAB, + trailing_semicolon: Optional[bool] = None, indent_closing_brace: bool = False, minify: bool = False, - ): - super().__init__() - self.indent = str(indent) - self.trailing_semicolon = trailing_semicolon - self.indent_closing_brace = indent_closing_brace - self.minify = minify - - def reset_style(self) -> None: + sort_keys: bool = False, + ) -> None: + + self._sort_keys: bool = sort_keys + self._indent_str: Optional[str] = None if minify else indent + + if minify: + self._key_separator: str = ':' + else: + self._key_separator = ": " + + if not indent and not minify: + self._item_separator: str = "; " + else: + self._item_separator = ';' + + if minify: + self._trailing_semicolon = False + elif trailing_semicolon is None: + self._trailing_semicolon = indent is not None + else: + self._trailing_semicolon = trailing_semicolon + + if indent_closing_brace and indent is not None: + self._indent_closing_brace = True + else: + self._indent_closing_brace = False + + self._minify = minify + + # TODO: deprecate + def reset_style(self) -> None: # pragma: no cover """ Reset the serializer to its default style. """ - # Reset CSS Parser to defaults - self.prefs.useDefaults() + self._set_options() - if self.minify: - self.prefs.useMinified() + def encode(self, obj: Mapping) -> str: + """ + Return a CSS representation of a Python dictionary. - else: - # Formatting preferences - self.prefs.omitLastSemicolon = not self.trailing_semicolon - self.prefs.indentClosingBrace = self.indent_closing_brace - self.prefs.indent = self.indent + :param obj: The Python dictionary to be serialized - @contextmanager - def use(self) -> Iterator: + :returns: The CSS string representation of the Python dictionary + """ + + return ''.join(self.iterencode(obj)) + + def iterencode(self, obj: Mapping) -> Iterable[str]: + """ + Encode the given dictionary and yield each part of the CSS string representation. + + :param obj: The Python dictionary to be serialized + + :returns: An iterable of strings representing the CSS serialization of the Python dictionary. """ - Contextmanager to use this serializer for the scope of the ``with`` block. + + if not isinstance(obj, Mapping): + raise TypeError(f"Cannot convert {type(obj)} to CSS") + + return self._iterencode_dict(obj, indent_level=-1) + + def default(self, obj: Any) -> Serializable: """ + Override this method in a subclass to implement custom serialization for objects that are not serializable by default. + + This method should return a serializable object. + If this method is not overridden, the encoder will raise a :exc:`ValueError` when trying to encode an unsupported object. + + :param obj: The object to be serialized that is not supported by default. + + :returns: A serializable object + + :raises: ValueError: If the object cannot be serialized + """ + + if self._default is not None: # pragma no cover # TODO + return self._default(obj) + + raise ValueError(f"Object of type {obj.__class__.__name__} cannot be represented in CSS") - # if css_parser.ser is self: - # yield - # return - # - current_serializer = css_parser.ser - self.reset_style() + def _encode_float(self, obj: float) -> str: + if obj != obj or obj == float("inf") or obj == float("-inf"): + raise ValueError(f"Out of range float values are not allowed: {repr(obj)}") + else: + return repr(obj) + + def _encode_str(self, obj: str) -> str: + + def replace_unicode(match: re.Match) -> str: # pragma: no cover # TODO + return ESCAPE_DCT[match.group(0)] + + return ESCAPE.sub(replace_unicode, obj) + + def _iterencode(self, obj: Any, indent_level: int) -> Iterable[str]: + if isinstance(obj, str): + yield self._encode_str(obj) + elif obj is True: + yield "true" + elif obj is False: + yield "false" + elif obj is None: + yield "none" + elif isinstance(obj, int): + yield repr(obj) + elif isinstance(obj, float): + yield self._encode_float(obj) + elif isinstance(obj, (list, tuple)): # pragma: no cover # TODO (needs default exposed) + yield from self._iterencode_list(obj, indent_level) + elif isinstance(obj, dict): # pragma: no cover # TODO (needs default exposed) + yield from self._iterencode_dict(obj, indent_level) + else: + if self._markers is not None: + marker_id: Optional[int] = id(obj) + if marker_id in self._markers: # pragma: no cover # TODO (super edge case) + raise ValueError("Circular reference detected") + assert marker_id is not None + self._markers[marker_id] = obj + else: + marker_id = None + + obj_user = self.default(obj) + yield from self._iterencode(obj_user, indent_level) # pragma: no cover # TODO (needs default exposed) + + if self._markers is not None and marker_id is not None: # pragma: no cover # TODO (needs default exposed) + del self._markers[marker_id] + + def _iterencode_list( + self, + obj: Union[list, tuple, None], + indent_level: int, + ) -> Iterable[str]: + + # this package + from dict2css import IMPORTANT + + if not obj: + raise ValueError("Property cannot be empty") + + if self._markers is not None: + marker_id: Optional[int] = id(obj) + if marker_id in self._markers: # pragma: no cover # TODO (super edge case) + raise ValueError("Circular reference detected") + assert marker_id is not None + self._markers[marker_id] = obj + else: + marker_id = None + + first: bool = True + for value in obj: + if first: + yield '' + first = False + else: + yield ' ' + + if value == IMPORTANT: + yield "!important" + else: + yield from self._iterencode(value, indent_level) + + if self._markers is not None and marker_id is not None: + del self._markers[marker_id] + + def _iterencode_dict( + self, + obj: Mapping[str, Any], + indent_level: int, + ) -> Iterable[str]: + if not obj: + if indent_level >= 0: + yield "{}" + + return + + if self._markers is not None: + marker_id: Optional[int] = id(obj) + if marker_id in self._markers: + raise ValueError("Circular reference detected") + assert marker_id is not None + self._markers[marker_id] = obj + else: + marker_id = None - try: - css_parser.ser = self - yield + if indent_level >= 0: + yield '{' + + minify_indent = False + if self._minify or not self._indent_str: + # No indent + newline_indent: Optional[str] = None + + if indent_level == -1: + indent_level += 1 + minify_indent = True + + else: + indent_level += 1 + newline_indent = '\n' + self._indent_str * indent_level + assert newline_indent is not None + + if indent_level > 0: + yield newline_indent + + first = True + if self._sort_keys: + items: Any = sorted(obj.items()) + else: + items = obj.items() + + total_items: int = len(items) + for idx, (key, value) in enumerate(items): + if not isinstance(key, str): + raise TypeError(f"keys must be strings, not {key.__class__.__name__}") + + if first: + first = False + elif newline_indent is not None: + yield newline_indent # we do not need to yield anything if indent == 0 + yield self._encode_str(key) + + if isinstance(value, dict): + if not self._minify: + yield ' ' + + yield from self._iterencode_dict(value, indent_level) + else: + yield self._key_separator + + if isinstance(value, (list, tuple)): + yield from self._iterencode_list(value, indent_level) + else: + yield from self._iterencode(value, indent_level) + + if idx != total_items - 1 or self._trailing_semicolon: + yield self._item_separator + + if self._indent_str: + indent_level -= 1 + yield '\n' + self._indent_str * indent_level + elif minify_indent: + indent_level -= 1 + + if indent_level >= 0: + if self._indent_closing_brace: + assert self._indent_str is not None + yield self._indent_str + + yield '}' + + if not self._minify: + yield '\n' + + if self._markers is not None and marker_id is not None: + del self._markers[marker_id] + + # TODO: deprecate + @contextmanager + def use(self) -> Iterator: # pragma: no cover + """ + No-op. Deprecated. + """ - finally: - css_parser.ser = current_serializer + yield diff --git a/doc-source/changelog.rst b/doc-source/changelog.rst index 7cc0218..4c38a44 100644 --- a/doc-source/changelog.rst +++ b/doc-source/changelog.rst @@ -6,7 +6,11 @@ Changelog 0.5.0 ------- -Drop support for Python 3.7 +* Drop support for Python 3.7 +* Reimplement ``load(s)`` using ``tinycss2`` and ``dump(s)`` using a modified version of ``ujson5`` +* Remove ``StyleSheet`` and ``make_style`` + +.. changelog:: 0.5.0 0.4.0 diff --git a/doc-source/conf.py b/doc-source/conf.py index d8b0a88..8c2a0f8 100644 --- a/doc-source/conf.py +++ b/doc-source/conf.py @@ -101,5 +101,4 @@ def setup(app): nitpicky = True latex_elements["preamble"] = "\\raggedbottom\n\\widowpenalty10000" -ignore_missing_xrefs = ["^css_parser\\."] changelog_sections_numbered = False diff --git a/pyproject.toml b/pyproject.toml index 42e57ff..64b8c56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -139,9 +139,6 @@ reformat = true [tool.snippet-fmt.languages.json] -[tool.dep_checker] -allowed_unused = [ "cssutils",] - [tool.dependency-dash."requirements.txt"] order = 10 diff --git a/repo_helper.yml b/repo_helper.yml index a29fa08..be33fbb 100644 --- a/repo_helper.yml +++ b/repo_helper.yml @@ -40,7 +40,6 @@ classifiers: sphinx_conf_epilogue: - nitpicky = True - latex_elements["preamble"] = "\\raggedbottom\n\\widowpenalty10000" - - ignore_missing_xrefs = ["^css_parser\\."] - changelog_sections_numbered = False exclude_files: @@ -54,6 +53,3 @@ extra_sphinx_extensions: - sphinx_toolbox_experimental.missing_xref - sphinx_toolbox_experimental.changelog - latex_mu - -tox_unmanaged: - - testenv diff --git a/requirements.txt b/requirements.txt index 5b4d1d8..241bfb1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,2 @@ -# css-parser>=1.0.6 -# Later cssutils polluted by AI and the new licence-breaking chardet -cssutils<=2.11.0,>=2.2.0 domdf-python-tools>=2.2.0 +tinycss2>=1.2.1 diff --git a/tests/test_dict2css.py b/tests/test_dict2css.py index 42301cb..ad275bb 100644 --- a/tests/test_dict2css.py +++ b/tests/test_dict2css.py @@ -1,55 +1,101 @@ # stdlib -from typing import Dict, Mapping, MutableMapping +from ipaddress import IPv4Address +from typing import Dict, Mapping, MutableMapping, no_type_check # 3rd party -import cssutils # type: ignore import pytest from coincidence.regressions import AdvancedDataRegressionFixture, AdvancedFileRegressionFixture from domdf_python_tools.paths import PathPlus -from domdf_python_tools.stringlist import StringList from domdf_python_tools.words import TAB # this package -from dict2css import IMPORTANT, Style, StyleSheet, dump, dumps, load, loads, make_style +from dict2css import IMPORTANT, Style, dump, dumps, load, loads from dict2css.helpers import em, px, rem -from dict2css.serializer import CSSSerializer -def test_stylesheet(advanced_file_regression: AdvancedFileRegressionFixture): - serializer = CSSSerializer(indent=" ", trailing_semicolon=True) +def boolean_option(name: str, id: str): # noqa: A002,MAN002 # pylint: disable=redefined-builtin + return pytest.mark.parametrize( + name, + [ + pytest.param(True, id=id), + pytest.param(False, id=f"not {id}"), + ], + ) + + +@no_type_check +def test_dumps_not_mapping(): + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps([1, 2, 3]) + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps((1, 2, 3)) + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps("ABC") + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps(123) + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps(123.456) + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps(True) + + with pytest.raises(TypeError, match="Cannot convert .* to CSS"): + dumps(None) - with serializer.use(): - sheet = StyleSheet() - # Body width - sheet.add_style(".wy-nav-content", {"max-width": (px(1200), IMPORTANT)}) +@no_type_check +@boolean_option("check_circular", "check_circular") +def test_dumps_unknown_type(check_circular: bool): + with pytest.raises(ValueError, match="Object of type .* cannot be represented in CSS"): + dumps({"the_key": IPv4Address("127.0.0.1")}, check_circular=check_circular) - # Spacing between list items - sheet.add_style("li p:last-child", {"margin-bottom": (px(12), IMPORTANT)}) - # Smooth scrolling between sections - sheet.add_style("html", {"scroll-behavior": "smooth"}) +@no_type_check +def test_dumps_bad_floats(): + with pytest.raises(ValueError, match="Out of range float values are not allowed:"): + dumps({"the_key": float("inf")}) - stylesheet = sheet.tostring().replace('}', "}\n") + with pytest.raises(ValueError, match="Out of range float values are not allowed:"): + dumps({"the_key": float("-inf")}) - advanced_file_regression.check(stylesheet, extension=".css") + with pytest.raises(ValueError, match="Out of range float values are not allowed:"): + dumps({"the_key": float("nan")}) -@pytest.mark.parametrize("trailing_semicolon", [True, False]) -@pytest.mark.parametrize("indent_closing_brace", [True, False]) -@pytest.mark.parametrize("indent", [TAB, " ", " "]) +@boolean_option("check_circular", "check_circular") +@boolean_option("sort_keys", "sort_keys") +@boolean_option("trailing_semicolon", "trailing_semicolon") +@boolean_option("indent_closing_brace", "indent_closing_brace") +@pytest.mark.parametrize( + "indent", + [ + pytest.param(TAB, id="tab"), + pytest.param(" ", id='2'), + pytest.param(" ", id='4'), + pytest.param('', id='0'), + ], + ) def test_dumps( advanced_file_regression: AdvancedFileRegressionFixture, trailing_semicolon: bool, indent_closing_brace: bool, indent: str, + check_circular: bool, + sort_keys: bool, tmp_pathplus: PathPlus, ): stylesheet: Dict[str, Style] = { - ".wy-nav-content": {"max-width": (rem(1200), IMPORTANT)}, + ".wy-nav-content": {"max-width": (rem(1200), IMPORTANT), "z-index": 999}, "li p:last-child": { "margin-bottom": (em(12), IMPORTANT), "margin-top": em(6), + "font-size": px(14), + "line-height": 1.5, + "font-weight": (800, IMPORTANT), }, "html": {"scroll-behavior": "smooth"}, } @@ -59,6 +105,8 @@ def test_dumps( indent=indent, trailing_semicolon=trailing_semicolon, indent_closing_brace=indent_closing_brace, + check_circular=check_circular, + sort_keys=sort_keys, ) advanced_file_regression.check(css, extension=".css") @@ -71,6 +119,8 @@ def test_dumps( indent=indent, trailing_semicolon=trailing_semicolon, indent_closing_brace=indent_closing_brace, + check_circular=check_circular, + sort_keys=sort_keys, ) advanced_file_regression.check_file(output_file) @@ -81,33 +131,16 @@ def test_dumps( indent=indent, trailing_semicolon=trailing_semicolon, indent_closing_brace=indent_closing_brace, + check_circular=check_circular, + sort_keys=sort_keys, ) advanced_file_regression.check_file(output_file) -def test_make_style(): - style: cssutils.css.CSSStyleRule = make_style("li p:last-child", {"max-width": (rem(1200), IMPORTANT)}) - assert str(style.selectorText) == "li p:last-child" - assert StringList(style.cssText) == [ - "li p:last-child {", - " max-width: 1200rem !important", - " }", - ] - - serializer = CSSSerializer(trailing_semicolon=True) - - with serializer.use(): - assert StringList(style.cssText) == [ - "li p:last-child {", - "\tmax-width: 1200rem !important;", - '}', - ] - - def test_dump_minify(advanced_file_regression: AdvancedFileRegressionFixture, tmp_pathplus: PathPlus): stylesheet: Dict[str, Style] = { - ".wy-nav-content": {"max-width": (rem(1200), IMPORTANT)}, + ".wy-nav-content": {"max-width": (rem(1200), IMPORTANT), "box-shadow": None}, "li p:last-child": { "margin-bottom": (em(12), IMPORTANT), "margin-top": em(6), @@ -192,3 +225,40 @@ def test_loads(advanced_data_regression: AdvancedDataRegressionFixture, tmp_path with style_file.open() as fp: assert load(fp) == stylesheet + + +def test_loads_bad_syntax(): + style = [ + ".wy-nav-content {", + " max-width", + " }", + ] + + with pytest.raises(ValueError, match=""): + loads('\n'.join(style)) + + +@no_type_check +def test_circular_references(): + css = { + 'a': {'b': 'c'}, + } + css['d'] = css + + with pytest.raises(ValueError, match="Circular reference detected"): + dumps(css) + + +def test_edge_cases(): + with pytest.raises(TypeError, match="keys must be strings, not"): + dumps({1234: {'a': 'b'}}) # type: ignore[dict-item] + + with pytest.raises(ValueError, match="Property cannot be empty"): + dumps({'a': {'b': ()}}) + + assert dumps({}) == '' + assert dumps({'a': {}}) == "a {}\n" + assert dumps({'a': {'b': True}}, indent='') == "a {b: true; }\n" + assert dumps({'a': {'b': False}}, indent='') == "a {b: false; }\n" + + assert dumps({'a': {'b': ('c', ('d', ))}}) == 'a {\n\tb: c d;\n}\n' diff --git a/tests/test_dict2css_/test_dump_minify.css b/tests/test_dict2css_/test_dump_minify.css index 210a232..d65e856 100644 --- a/tests/test_dict2css_/test_dump_minify.css +++ b/tests/test_dict2css_/test_dump_minify.css @@ -1 +1 @@ -.wy-nav-content{max-width:1200rem !important}li p:last-child{margin-bottom:12em !important;margin-top:6em}html{scroll-behavior:smooth} +.wy-nav-content{max-width:1200rem !important;box-shadow:none}li p:last-child{margin-bottom:12em !important;margin-top:6em}html{scroll-behavior:smooth} diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..187f96e --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important} +html {scroll-behavior: smooth} diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..187f96e --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important} +html {scroll-behavior: smooth} diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..b71a82a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +html {scroll-behavior: smooth} +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em} diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..b71a82a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +html {scroll-behavior: smooth} +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em} diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..ff02894 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important; } +html {scroll-behavior: smooth; } diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..ff02894 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important; } +html {scroll-behavior: smooth; } diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..7c02e55 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +html {scroll-behavior: smooth; } +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em; } diff --git a/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..7c02e55 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +html {scroll-behavior: smooth; } +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em; } diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..187f96e --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important} +html {scroll-behavior: smooth} diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..187f96e --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important} +html {scroll-behavior: smooth} diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..b71a82a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +html {scroll-behavior: smooth} +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em} diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..b71a82a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999} +html {scroll-behavior: smooth} +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em} diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..ff02894 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important; } +html {scroll-behavior: smooth; } diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..ff02894 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +li p:last-child {margin-bottom: 12em !important; margin-top: 6em; font-size: 14px; line-height: 1.5; font-weight: 800 !important; } +html {scroll-behavior: smooth; } diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..7c02e55 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +html {scroll-behavior: smooth; } +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em; } diff --git a/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..7c02e55 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_0_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,3 @@ +.wy-nav-content {max-width: 1200rem !important; z-index: 999; } +html {scroll-behavior: smooth; } +li p:last-child {font-size: 14px; font-weight: 800 !important; line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em; } diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..6afd4a9 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..6afd4a9 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps____True_False_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 53% rename from tests/test_dict2css_/test_dumps____True_False_.css rename to tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index bac0891..c6d1b0d 100644 --- a/tests/test_dict2css_/test_dumps____True_False_.css +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth - } diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..c6d1b0d --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em + } diff --git a/tests/test_dict2css_/test_dumps____True_True_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 66% rename from tests/test_dict2css_/test_dumps____True_True_.css rename to tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index 639a7ab..905e248 100644 --- a/tests/test_dict2css_/test_dumps____True_True_.css +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..905e248 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; + } + +html { + scroll-behavior: smooth; + } diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..5c89a40 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..5c89a40 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..5c14ff5 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..5c14ff5 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps____False_False_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 52% rename from tests/test_dict2css_/test_dumps____False_False_.css rename to tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index be1415b..b18f4e0 100644 --- a/tests/test_dict2css_/test_dumps____False_False_.css +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth -} diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..b18f4e0 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em +} diff --git a/tests/test_dict2css_/test_dumps____False_True_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 65% rename from tests/test_dict2css_/test_dumps____False_True_.css rename to tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index 1cf3c1d..2dc8aba 100644 --- a/tests/test_dict2css_/test_dumps____False_True_.css +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..2dc8aba --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; +} + +html { + scroll-behavior: smooth; +} diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..b0dc652 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..b0dc652 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_2_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..ffbd0e7 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..ffbd0e7 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps______True_False_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 53% rename from tests/test_dict2css_/test_dumps______True_False_.css rename to tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index cce7634..8718aed 100644 --- a/tests/test_dict2css_/test_dumps______True_False_.css +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth - } diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..8718aed --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em + } diff --git a/tests/test_dict2css_/test_dumps______True_True_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 66% rename from tests/test_dict2css_/test_dumps______True_True_.css rename to tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index 056d939..67a5fe0 100644 --- a/tests/test_dict2css_/test_dumps______True_True_.css +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..67a5fe0 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; + } + +html { + scroll-behavior: smooth; + } diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..49a3b1a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..49a3b1a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..76b9976 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..76b9976 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps______False_False_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 51% rename from tests/test_dict2css_/test_dumps______False_False_.css rename to tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index 43fbdb2..9adc67a 100644 --- a/tests/test_dict2css_/test_dumps______False_False_.css +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth -} diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..9adc67a --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em +} diff --git a/tests/test_dict2css_/test_dumps______False_True_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 64% rename from tests/test_dict2css_/test_dumps______False_True_.css rename to tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index d84370c..19c3f36 100644 --- a/tests/test_dict2css_/test_dumps______False_True_.css +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..19c3f36 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; +} + +html { + scroll-behavior: smooth; +} diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..8a67610 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..8a67610 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_4_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..fa2263f --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..fa2263f --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important + } + +html { + scroll-behavior: smooth + } diff --git a/tests/test_dict2css_/test_dumps__t_True_False_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 53% rename from tests/test_dict2css_/test_dumps__t_True_False_.css rename to tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index bbe19ce..306b110 100644 --- a/tests/test_dict2css_/test_dumps__t_True_False_.css +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth - } diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..306b110 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 + } + +html { + scroll-behavior: smooth + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em + } diff --git a/tests/test_dict2css_/test_dumps__t_True_True_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 66% rename from tests/test_dict2css_/test_dumps__t_True_True_.css rename to tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index 3c47fb8..60d3152 100644 --- a/tests/test_dict2css_/test_dumps__t_True_True_.css +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..60d3152 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; + } + +html { + scroll-behavior: smooth; + } diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..19529d1 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..19529d1 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; + } + +html { + scroll-behavior: smooth; + } + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; + } diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css new file mode 100644 index 0000000..ba6d847 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..ba6d847 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important +} + +html { + scroll-behavior: smooth +} diff --git a/tests/test_dict2css_/test_dumps__t_False_False_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css similarity index 52% rename from tests/test_dict2css_/test_dumps__t_False_False_.css rename to tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css index fe9a067..1efa5e5 100644 --- a/tests/test_dict2css_/test_dumps__t_False_False_.css +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_check_circular_.css @@ -1,12 +1,16 @@ .wy-nav-content { - max-width: 1200rem !important + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth } li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; margin-bottom: 12em !important; margin-top: 6em } - -html { - scroll-behavior: smooth -} diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..1efa5e5 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_not_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999 +} + +html { + scroll-behavior: smooth +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em +} diff --git a/tests/test_dict2css_/test_dumps__t_False_True_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css similarity index 66% rename from tests/test_dict2css_/test_dumps__t_False_True_.css rename to tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css index 6b4100e..d5a9c42 100644 --- a/tests/test_dict2css_/test_dumps__t_False_True_.css +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_check_circular_.css @@ -1,10 +1,14 @@ .wy-nav-content { max-width: 1200rem !important; + z-index: 999; } li p:last-child { margin-bottom: 12em !important; margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; } html { diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..d5a9c42 --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_not_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +li p:last-child { + margin-bottom: 12em !important; + margin-top: 6em; + font-size: 14px; + line-height: 1.5; + font-weight: 800 !important; +} + +html { + scroll-behavior: smooth; +} diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css new file mode 100644 index 0000000..fb0383d --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css new file mode 100644 index 0000000..fb0383d --- /dev/null +++ b/tests/test_dict2css_/test_dumps_tab_not_indent_closing_brace_trailing_semicolon_sort_keys_not_check_circular_.css @@ -0,0 +1,16 @@ +.wy-nav-content { + max-width: 1200rem !important; + z-index: 999; +} + +html { + scroll-behavior: smooth; +} + +li p:last-child { + font-size: 14px; + font-weight: 800 !important; + line-height: 1.5; + margin-bottom: 12em !important; + margin-top: 6em; +} diff --git a/tests/test_dict2css_/test_stylesheet.css b/tests/test_dict2css_/test_stylesheet.css deleted file mode 100644 index 2fe26dc..0000000 --- a/tests/test_dict2css_/test_stylesheet.css +++ /dev/null @@ -1,11 +0,0 @@ -.wy-nav-content { - max-width: 1200px !important; -} - -li p:last-child { - margin-bottom: 12px !important; -} - -html { - scroll-behavior: smooth; -} diff --git a/tox.ini b/tox.ini index c249c9e..74f65f8 100644 --- a/tox.ini +++ b/tox.ini @@ -2,6 +2,7 @@ # You may add new sections, but any changes made to the following sections will be lost: # * tox # * envlists +# * testenv # * testenv:.package # * testenv:py313-dev # * testenv:py313 @@ -35,6 +36,17 @@ test = py38, py39, py310, py311, py312, py313, pypy38, pypy39 qa = mypy, lint cov = py39, coverage +[testenv] +setenv = + PYTHONDEVMODE=1 + PIP_DISABLE_PIP_VERSION_CHECK=1 + SETUPTOOLS_USE_DISTUTILS=stdlib +download = True +deps = -r{toxinidir}/tests/requirements.txt +commands = + python --version + python -m pytest --cov=dict2css -r aR tests/ {posargs} + [testenv:.package] setenv = PYTHONDEVMODE=1 @@ -203,15 +215,3 @@ package = dict2css [pytest] addopts = --color yes --durations 25 timeout = 300 - -[testenv] -setenv = - PYTHONDEVMODE=1 - PIP_DISABLE_PIP_VERSION_CHECK=1 -deps = -r{toxinidir}/tests/requirements.txt -commands = - python --version - python -m pip uninstall css-parser -y - python -m pytest --cov=dict2css -r aR tests/ {posargs} - python -m pip install "css-parser>=1.0.6" - python -m pytest --cov=dict2css -r aR tests/ --cov-append {posargs}