2026-10-11 15:05:42 +03:00
|
|
|
"""The section 5.2 comparison: an unmodified copy, plus added @font-face rules."""
|
|
|
|
|
|
refactor: split the repo into self-contained validator, directory, quickstart, spec and site folders
validator/ holds mewslint (lint, css, fetch, DTD/CSS data); directory/ holds
the mews.page service (app, db, check, pages, cli) and depends on validator/;
quickstart/ holds mews-quickstart and md2mews.py for third parties who want
to create Mews content without cloning the repo; spec/ consolidates doc/ and
dtd/ with the canonical mews-0.1.css; site/ becomes a Pelican project with
the forward-facing pages as Markdown, the check form kept as a raw HTML
snippet. Root pyproject.toml is now a virtual uv workspace over validator,
directory and quickstart, with cross-cutting tests that span more than one
of them staying at the repo root. Makefile and flake.nix updated to match.
2026-10-13 12:29:23 +03:00
|
|
|
from importlib import resources
|
|
|
|
|
|
2026-10-11 15:05:42 +03:00
|
|
|
from mews import css
|
|
|
|
|
|
refactor: split the repo into self-contained validator, directory, quickstart, spec and site folders
validator/ holds mewslint (lint, css, fetch, DTD/CSS data); directory/ holds
the mews.page service (app, db, check, pages, cli) and depends on validator/;
quickstart/ holds mews-quickstart and md2mews.py for third parties who want
to create Mews content without cloning the repo; spec/ consolidates doc/ and
dtd/ with the canonical mews-0.1.css; site/ becomes a Pelican project with
the forward-facing pages as Markdown, the check form kept as a raw HTML
snippet. Root pyproject.toml is now a virtual uv workspace over validator,
directory and quickstart, with cross-cutting tests that span more than one
of them staying at the repo root. Makefile and flake.nix updated to match.
2026-10-13 12:29:23 +03:00
|
|
|
CANONICAL = resources.files("mews.data").joinpath("mews-0.1.css").read_text("utf-8")
|
2026-10-11 15:05:42 +03:00
|
|
|
|
|
|
|
|
FONT_FACE = """@font-face {
|
|
|
|
|
font-family: "Atkinson Hyperlegible";
|
|
|
|
|
src: url(/fonts/atkinson.woff2) format("woff2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_an_unmodified_copy_passes():
|
|
|
|
|
assert css.compare(CANONICAL).equal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_line_endings_and_trailing_spaces_do_not_matter():
|
|
|
|
|
mangled = CANONICAL.replace("\n", " \r\n") + "\n\n\n"
|
|
|
|
|
assert css.compare(mangled).equal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_an_added_font_face_passes_and_is_read():
|
|
|
|
|
result = css.compare(FONT_FACE + CANONICAL)
|
|
|
|
|
assert result.equal
|
|
|
|
|
assert result.font_urls == ["/fonts/atkinson.woff2"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_a_font_face_at_the_end_also_passes():
|
|
|
|
|
assert css.compare(CANONICAL + "\n" + FONT_FACE).equal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_a_changed_rule_fails_with_a_line_number():
|
|
|
|
|
result = css.compare(CANONICAL.replace("#faf8f3", "#ffffff"))
|
|
|
|
|
assert not result.equal
|
|
|
|
|
assert result.diff_line == 5
|
|
|
|
|
assert "background-color" in result.diff
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_a_reordered_rule_fails():
|
|
|
|
|
lines = CANONICAL.split("\n")
|
|
|
|
|
swapped = "\n".join([*lines[:4], lines[5], lines[4], *lines[6:]])
|
|
|
|
|
assert not css.compare(swapped).equal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_a_removed_rule_fails():
|
|
|
|
|
assert not css.compare(CANONICAL.replace("hr {", "hr-off {")).equal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_an_import_is_noticed():
|
|
|
|
|
assert css.compare('@import url("x.css");\n' + CANONICAL).has_import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_a_font_face_inside_a_media_query_is_not_stripped():
|
|
|
|
|
inner = "@media screen {\n" + FONT_FACE + "}\n"
|
|
|
|
|
result = css.compare(CANONICAL + inner)
|
|
|
|
|
assert not result.equal
|