Skip to content

Commit

Permalink
crystal.doc.css: Test
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfstr committed Sep 5, 2023
1 parent 6871d1d commit 4cb2361
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
7 changes: 3 additions & 4 deletions src/crystal/doc/css.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
Parses CSS documents.
"""

from __future__ import annotations

from crystal.doc.generic import Document, Link
import tinycss2
from tinycss2 import ast
from tinycss2.serializer import serialize_string_value, serialize_url
from typing import List, Tuple


def parse_css_and_links(
body_bytes: bytes,
declared_charset: str=None
) -> tuple[CssDocument, list[Link]]:
) -> 'Tuple[CssDocument, List[Link]]':
(rules, encoding) = tinycss2.parse_stylesheet_bytes(
body_bytes,
protocol_encoding=declared_charset)

links = [] # type: list[Link]
links = [] # type: List[Link]
for rule in rules:
if isinstance(rule, ast.QualifiedRule) or isinstance(rule, ast.AtRule):
if rule.content is not None: # has been observed as None in the wild sometimes
Expand Down
68 changes: 68 additions & 0 deletions tests/test_parse_css.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from crystal.doc.css import CssDocument
from crystal.doc.css import parse_css_and_links as try_parse_css_and_links
from crystal.doc.generic import Document, Link
from textwrap import dedent
from typing import Optional, Tuple
from unittest import skip

# === Tests ===

# TODO: Extend each "test_recognizes_*" to also test WRITING
# to the relative_url of the output link to ensure it
# gets saves in a reasonable way.

def test_can_parse_and_format_basic_css_document() -> None:
INPUT_CSS_BYTES = dedent(
"""
html {
background-color: cyan;
}
"""
).lstrip('\n').encode('utf-8')
EXPECTED_OUTPUT_CSS_STR = dedent(
"""
html {
background-color: cyan;
}
"""
).lstrip('\n')

(doc, _) = _parse_css_and_links(INPUT_CSS_BYTES)

assert isinstance(doc, CssDocument)
assert EXPECTED_OUTPUT_CSS_STR == str(doc)


def test_recognizes_url_token_link() -> None:
(_, (link,)) = _parse_css_and_links(
"""body { background: url(background.png) }""".encode('utf-8'))
assert 'background.png' == link.relative_url
assert 'CSS URL Reference' == link.type_title
assert True == link.embedded


def test_recognizes_url_function_link() -> None:
(_, (link,)) = _parse_css_and_links(
"""body { background: url("background.png") }""".encode('utf-8'))
assert 'background.png' == link.relative_url
assert 'CSS URL Reference' == link.type_title
assert True == link.embedded


def test_recognizes_import_string_link() -> None:
(_, (link,)) = _parse_css_and_links(
"""@import "page.js" """.encode('utf-8'))
assert 'page.js' == link.relative_url
assert 'CSS @import' == link.type_title
assert True == link.embedded


# === Utility ===

def _parse_css_and_links(
css_bytes: bytes,
*, declared_charset: Optional[str]=None,
) -> 'Tuple[Document, List[Link]]':
result = try_parse_css_and_links(css_bytes, declared_charset)
assert result is not None
return result
4 changes: 4 additions & 0 deletions tests/test_parse_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

# === Tests ===

# TODO: Extend each "test_recognizes_*" to also test WRITING
# to the relative_url of the output link to ensure it
# gets saves in a reasonable way.

def test_can_parse_and_format_basic_html_document() -> None:
with SubtestsContext('test_can_parse_and_format_basic_html_document').run() as subtests:
for html_parser_type in HTML_PARSER_TYPE_CHOICES:
Expand Down

0 comments on commit 4cb2361

Please sign in to comment.