more formal map tests

This commit is contained in:
Jesse Bannon 2023-11-10 09:50:56 -08:00
parent f9c30f9f7f
commit df462ce265
2 changed files with 68 additions and 17 deletions

View file

@ -21,6 +21,13 @@ from ytdl_sub.validators.string_formatter_validators import is_valid_source_vari
# 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:
def __init__(self, text: str):
@ -189,7 +196,7 @@ class _Parser:
comma_count += 1
if argument_index != comma_count:
self._set_highlight_position()
raise InvalidSyntaxException("Unexpected comma when parsing arguments")
raise UNEXPECTED_ARGUMENT
self._pos += 1
else:
@ -243,32 +250,39 @@ class _Parser:
while ch := self._read(increment_pos=False):
if ch == "}":
if key is not None:
raise InvalidSyntaxException("Map has a key with no value")
raise MAP_KEY_WITH_NO_VALUE
self._pos += 1
return UnresolvedMap(value=output)
elif ch == ",":
if in_comma:
raise StringFormattingException("Comma followed by comma")
raise UNEXPECTED_ARGUMENT
if key is not None:
raise InvalidSyntaxException("Map has a key with no value")
if output is None:
raise InvalidSyntaxException("Map has an extra comma")
raise MAP_KEY_WITH_NO_VALUE
if not output:
raise UNEXPECTED_ARGUMENT
in_comma = True
self._pos += 1
elif key is None:
self._set_highlight_position()
in_comma = False
key_args = self._parse_args(breaking_chars=":")
if len(key_args) != 1:
raise StringFormattingException("Lazy parsing but got mlutiple args")
key_args = self._parse_args(breaking_chars=":}")
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]
elif key is not None and ch == ":":
self._set_highlight_position()
self._pos += 1
value_args = self._parse_args(breaking_chars=",}")
if len(value_args) != 1:
raise InvalidSyntaxException("Map has a key with no value")
if len(value_args) == 0:
raise MAP_KEY_WITH_NO_VALUE
if len(value_args) > 1:
raise StringFormattingException("map has key with multiple values")
output[key] = value_args[0]
key = None

View file

@ -2,6 +2,10 @@ import re
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.types.map import ResolvedMap
from ytdl_sub.script.types.resolvable import Float
@ -57,8 +61,17 @@ class TestMap:
)
}
def test_empty_map(self):
assert Script({"map": "{{}}"}).resolve() == {"map": ResolvedMap({})}
@pytest.mark.parametrize(
"empty_map",
[
"{{}}",
"{{ }}",
"{{ }}",
"{{\n}}",
],
)
def test_empty_map(self, empty_map: str):
assert Script({"map": empty_map}).resolve() == {"map": ResolvedMap({})}
@pytest.mark.parametrize(
"value",
@ -72,18 +85,42 @@ class TestMap:
],
)
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()
@pytest.mark.parametrize(
"value",
[
"{{,}}",
"{{ , }}",
"{{'key':'value',,}}",
"{{'key': 'value', ,}}",
],
)
def test_map_unexpected_comma(self, value: str):
with pytest.raises(
InvalidSyntaxException, match=re.escape("Unexpected comma when parsing arguments")
):
with pytest.raises(InvalidSyntaxException, match=re.escape(str(UNEXPECTED_ARGUMENT))):
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()