more formal map tests
This commit is contained in:
parent
f9c30f9f7f
commit
df462ce265
2 changed files with 68 additions and 17 deletions
|
|
@ -21,6 +21,13 @@ from ytdl_sub.validators.string_formatter_validators import is_valid_source_vari
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
|
|
||||||
|
UNEXPECTED_ARGUMENT = InvalidSyntaxException("Unexpected comma when parsing arguments")
|
||||||
|
MAP_KEY_WITH_NO_VALUE = InvalidSyntaxException("Map has a key with no value")
|
||||||
|
MAP_KEY_MULTIPLE_VALUES = InvalidSyntaxException(
|
||||||
|
"Map key has multiple values when there should only be one"
|
||||||
|
)
|
||||||
|
MAP_MISSING_KEY = InvalidSyntaxException("Map has a missing key")
|
||||||
|
|
||||||
|
|
||||||
class _Parser:
|
class _Parser:
|
||||||
def __init__(self, text: str):
|
def __init__(self, text: str):
|
||||||
|
|
@ -189,7 +196,7 @@ class _Parser:
|
||||||
comma_count += 1
|
comma_count += 1
|
||||||
if argument_index != comma_count:
|
if argument_index != comma_count:
|
||||||
self._set_highlight_position()
|
self._set_highlight_position()
|
||||||
raise InvalidSyntaxException("Unexpected comma when parsing arguments")
|
raise UNEXPECTED_ARGUMENT
|
||||||
|
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
else:
|
else:
|
||||||
|
|
@ -243,32 +250,39 @@ class _Parser:
|
||||||
while ch := self._read(increment_pos=False):
|
while ch := self._read(increment_pos=False):
|
||||||
if ch == "}":
|
if ch == "}":
|
||||||
if key is not None:
|
if key is not None:
|
||||||
raise InvalidSyntaxException("Map has a key with no value")
|
raise MAP_KEY_WITH_NO_VALUE
|
||||||
|
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
return UnresolvedMap(value=output)
|
return UnresolvedMap(value=output)
|
||||||
elif ch == ",":
|
elif ch == ",":
|
||||||
if in_comma:
|
if in_comma:
|
||||||
raise StringFormattingException("Comma followed by comma")
|
raise UNEXPECTED_ARGUMENT
|
||||||
if key is not None:
|
if key is not None:
|
||||||
raise InvalidSyntaxException("Map has a key with no value")
|
raise MAP_KEY_WITH_NO_VALUE
|
||||||
if output is None:
|
if not output:
|
||||||
raise InvalidSyntaxException("Map has an extra comma")
|
raise UNEXPECTED_ARGUMENT
|
||||||
in_comma = True
|
in_comma = True
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
elif key is None:
|
elif key is None:
|
||||||
self._set_highlight_position()
|
self._set_highlight_position()
|
||||||
in_comma = False
|
in_comma = False
|
||||||
key_args = self._parse_args(breaking_chars=":")
|
key_args = self._parse_args(breaking_chars=":}")
|
||||||
if len(key_args) != 1:
|
|
||||||
raise StringFormattingException("Lazy parsing but got mlutiple args")
|
if len(key_args) == 0 and self._read(increment_pos=False) == "}":
|
||||||
|
continue # will return the map next iteration
|
||||||
|
if len(key_args) == 0:
|
||||||
|
raise MAP_MISSING_KEY
|
||||||
|
if len(key_args) > 1:
|
||||||
|
raise MAP_KEY_MULTIPLE_VALUES
|
||||||
key = key_args[0]
|
key = key_args[0]
|
||||||
elif key is not None and ch == ":":
|
elif key is not None and ch == ":":
|
||||||
self._set_highlight_position()
|
self._set_highlight_position()
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
value_args = self._parse_args(breaking_chars=",}")
|
value_args = self._parse_args(breaking_chars=",}")
|
||||||
if len(value_args) != 1:
|
if len(value_args) == 0:
|
||||||
raise InvalidSyntaxException("Map has a key with no value")
|
raise MAP_KEY_WITH_NO_VALUE
|
||||||
|
if len(value_args) > 1:
|
||||||
|
raise StringFormattingException("map has key with multiple values")
|
||||||
|
|
||||||
output[key] = value_args[0]
|
output[key] = value_args[0]
|
||||||
key = None
|
key = None
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from ytdl_sub.script.parser import MAP_KEY_MULTIPLE_VALUES
|
||||||
|
from ytdl_sub.script.parser import MAP_KEY_WITH_NO_VALUE
|
||||||
|
from ytdl_sub.script.parser import MAP_MISSING_KEY
|
||||||
|
from ytdl_sub.script.parser import UNEXPECTED_ARGUMENT
|
||||||
from ytdl_sub.script.script import Script
|
from ytdl_sub.script.script import Script
|
||||||
from ytdl_sub.script.types.map import ResolvedMap
|
from ytdl_sub.script.types.map import ResolvedMap
|
||||||
from ytdl_sub.script.types.resolvable import Float
|
from ytdl_sub.script.types.resolvable import Float
|
||||||
|
|
@ -57,8 +61,17 @@ class TestMap:
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_empty_map(self):
|
@pytest.mark.parametrize(
|
||||||
assert Script({"map": "{{}}"}).resolve() == {"map": ResolvedMap({})}
|
"empty_map",
|
||||||
|
[
|
||||||
|
"{{}}",
|
||||||
|
"{{ }}",
|
||||||
|
"{{ }}",
|
||||||
|
"{{\n}}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_empty_map(self, empty_map: str):
|
||||||
|
assert Script({"map": empty_map}).resolve() == {"map": ResolvedMap({})}
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"value",
|
"value",
|
||||||
|
|
@ -72,18 +85,42 @@ class TestMap:
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_key_has_no_value(self, value: str):
|
def test_key_has_no_value(self, value: str):
|
||||||
with pytest.raises(InvalidSyntaxException, match=re.escape("Map has a key with no value")):
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(MAP_KEY_WITH_NO_VALUE))):
|
||||||
Script({"map": value}).resolve()
|
Script({"map": value}).resolve()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"value",
|
"value",
|
||||||
[
|
[
|
||||||
|
"{{,}}",
|
||||||
"{{ , }}",
|
"{{ , }}",
|
||||||
|
"{{'key':'value',,}}",
|
||||||
"{{'key': 'value', ,}}",
|
"{{'key': 'value', ,}}",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_map_unexpected_comma(self, value: str):
|
def test_map_unexpected_comma(self, value: str):
|
||||||
with pytest.raises(
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(UNEXPECTED_ARGUMENT))):
|
||||||
InvalidSyntaxException, match=re.escape("Unexpected comma when parsing arguments")
|
Script({"map": value}).resolve()
|
||||||
):
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value",
|
||||||
|
[
|
||||||
|
"{{'key1','key2'}}",
|
||||||
|
"{{'key1' , 'key2'}}",
|
||||||
|
"{{ 'key1', 'key2': 'value' }}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_map_multiple_keys(self, value: str):
|
||||||
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(MAP_KEY_MULTIPLE_VALUES))):
|
||||||
|
Script({"map": value}).resolve()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"value",
|
||||||
|
[
|
||||||
|
"{{:}}",
|
||||||
|
"{{ : }}",
|
||||||
|
"{{ : 'value' }}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_map_missing_key(self, value: str):
|
||||||
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(MAP_MISSING_KEY))):
|
||||||
Script({"map": value}).resolve()
|
Script({"map": value}).resolve()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue