Invalid pseudo selectors (#2445)

* token error

* error on bad pseudo selectors
This commit is contained in:
Will McGugan
2023-05-01 16:22:35 +01:00
committed by GitHub
parent 08de9a0fca
commit 20a1612361
4 changed files with 82 additions and 31 deletions

View File

@@ -61,6 +61,14 @@ VALID_STYLE_FLAGS: Final = {
"underline",
"uu",
}
VALID_PSEUDO_CLASSES: Final = {
"blur",
"disabled",
"enabled",
"focus-within",
"focus",
"hover",
}
NULL_SPACING: Final = Spacing.all(0)

View File

@@ -12,7 +12,9 @@ from rich.panel import Panel
from rich.syntax import Syntax
from rich.text import Text
from ..suggestions import get_suggestion
from ._error_tools import friendly_list
from .constants import VALID_PSEUDO_CLASSES
class TokenError(Exception):
@@ -56,7 +58,7 @@ class TokenError(Exception):
line_numbers=True,
indent_guides=True,
line_range=(max(0, line_no - 2), line_no + 2),
highlight_lines={line_no},
highlight_lines={line_no + 1},
)
syntax.stylize_range("reverse bold", self.start, self.end)
return Panel(syntax, border_style="red")
@@ -227,6 +229,29 @@ class Tokenizer:
(line_no, col_no),
referenced_by=None,
)
if (
token.name == "pseudo_class"
and token.value.strip(":") not in VALID_PSEUDO_CLASSES
):
pseudo_class = token.value.strip(":")
suggestion = get_suggestion(pseudo_class, list(VALID_PSEUDO_CLASSES))
all_valid = f"must be one of {friendly_list(VALID_PSEUDO_CLASSES)}"
if suggestion:
raise TokenError(
self.path,
self.code,
(line_no, col_no),
f"unknown pseudo-class {pseudo_class!r}; did you mean {suggestion!r}?; {all_valid}",
)
else:
raise TokenError(
self.path,
self.code,
(line_no, col_no),
f"unknown pseudo-class {pseudo_class!r}; {all_valid}",
)
col_no += len(value)
if col_no >= len(line):
line_no += 1

View File

@@ -140,52 +140,52 @@ A1
/**********************************************************************/
A:foo {}
A:foo:bar {}
A:focus {}
A:focus:hover {}
A
:foo {}
:focus {}
A
:foo:bar {}
:focus:hover {}
A
:foo
:bar {}
A:foo-bar {}
:focus
:hover {}
A:enabled {}
A
:foo-bar {}
:enabled {}
A :foo {}
A :foo :bar {}
A :foo-bar {}
A :focus {}
A :focus :hover {}
A :enabled {}
.A:foo {}
.A:foo:bar {}
.A:focus {}
.A:focus:hover {}
.A
:foo {}
:focus {}
.A
:foo:bar {}
:focus:hover {}
.A
:foo
:bar {}
.A:foo-bar {}
:focus
:hover {}
.A:enabled {}
.A
:foo-bar {}
:enabled {}
#A:foo {}
#A:foo:bar {}
#A:focus {}
#A:focus:hover {}
#A
:foo {}
:focus {}
#A
:foo:bar {}
:focus:hover {}
#A
:foo
:bar {}
#A:foo-bar {}
:focus
:hover {}
#A:enabled {}
#A
:foo-bar {}
:enabled {}
A1.A1.A1:foo {}
A1.A1#A1:foo {}
A1:foo.A1:foo#A1:foo {}
A1.A1.A1:focus {}
A1.A1#A1:focus {}
A1:focus.A1:focus#A1:focus {}
/**********************************************************************/

View File

@@ -1226,3 +1226,21 @@ class TestTypeNames:
stylesheet.add_source(f"StartType {separator} 1TestType {{}}")
with pytest.raises(TokenError):
stylesheet.parse()
def test_parse_bad_psuedo_selector():
"""Check unknown selector raises a token error."""
bad_selector = """\
Widget:foo{
border: red;
}
"""
stylesheet = Stylesheet()
stylesheet.add_source(bad_selector, "foo")
with pytest.raises(TokenError) as error:
stylesheet.parse()
assert error.value.start == (0, 6)