int tests WIP

This commit is contained in:
Jesse Bannon 2023-11-11 01:11:06 -08:00
parent 7f0ccd5f3c
commit b86ff252e5
3 changed files with 99 additions and 6 deletions

View file

@ -41,6 +41,11 @@ UNREACHABLE = UnreachableSyntaxException(
BRACKET_NOT_CLOSED = InvalidSyntaxException("Bracket not properly closed") BRACKET_NOT_CLOSED = InvalidSyntaxException("Bracket not properly closed")
NUMERICS_ONLY_ARGS = InvalidSyntaxException(
"Numerics can only be used as arguments to functions, maps, or arrays"
)
NUMERICS_INVALID_CHAR = InvalidSyntaxException("Invalid value when parsing a numeric")
def UNEXPECTED_CHAR_ARGUMENT(parser: ArgumentParser): def UNEXPECTED_CHAR_ARGUMENT(parser: ArgumentParser):
return InvalidSyntaxException(f"Unexpected character when parsing {parser.value} arguments") return InvalidSyntaxException(f"Unexpected character when parsing {parser.value} arguments")
@ -64,6 +69,10 @@ def _is_variable_start(char: str) -> bool:
return char.isalpha() and char.islower() return char.isalpha() and char.islower()
def _is_numeric_start(char: str) -> bool:
return char.isnumeric() or char == "-"
class _Parser: class _Parser:
def __init__(self, text: str): def __init__(self, text: str):
self._text = text self._text = text
@ -154,17 +163,38 @@ class _Parser:
def _parse_numeric(self) -> Integer | Float: def _parse_numeric(self) -> Integer | Float:
numeric_string = "" numeric_string = ""
if self._read(increment_pos=False) == "-":
numeric_string += "-"
self._pos += 1
if has_decimal := (self._read(increment_pos=False) == "."):
numeric_string += "."
self._pos += 1
while ch := self._read(increment_pos=False): while ch := self._read(increment_pos=False):
if not (ch.isnumeric() or ch == "."): if ch == "-":
break raise NUMERICS_INVALID_CHAR
if ch == ".":
if has_decimal:
raise NUMERICS_INVALID_CHAR
has_decimal = True
self._pos += 1 self._pos += 1
numeric_string += ch numeric_string += ch
elif ch.isnumeric():
self._pos += 1
numeric_string += ch
else:
break
if numeric_string == "." or numeric_string == "-":
raise NUMERICS_INVALID_CHAR
try: try:
numeric_float = float(numeric_string) numeric_float = float(numeric_string)
except ValueError: except ValueError:
raise StringFormattingException(f"Invalid numeric: {numeric_string}") raise UNREACHABLE
if (numeric_int := int(numeric_float)) == numeric_float: if (numeric_int := int(numeric_float)) == numeric_float:
return Integer(value=numeric_int) return Integer(value=numeric_int)
@ -190,7 +220,7 @@ class _Parser:
if self._read(increment_pos=False) == "%": if self._read(increment_pos=False) == "%":
self._pos += 1 self._pos += 1
return self._parse_function() return self._parse_function()
if self._read(increment_pos=False).isnumeric(): if _is_numeric_start(self._read(increment_pos=False)):
return self._parse_numeric() return self._parse_numeric()
if (self._read(increment_pos=False, length=4) or "").lower() == "true": if (self._read(increment_pos=False, length=4) or "").lower() == "true":
self._pos += 4 self._pos += 4
@ -377,6 +407,8 @@ class _Parser:
self._ast.append(self._parse_map()) self._ast.append(self._parse_map())
elif _is_variable_start(ch1): elif _is_variable_start(ch1):
self._ast.append(self._parse_variable()) self._ast.append(self._parse_variable())
elif _is_numeric_start(ch1):
raise NUMERICS_ONLY_ARGS
else: else:
raise UNEXPECTED_CHAR_ARGUMENT(parser=ArgumentParser.SCRIPT) raise UNEXPECTED_CHAR_ARGUMENT(parser=ArgumentParser.SCRIPT)
elif bracket_counter == 0: elif bracket_counter == 0:

View file

@ -2,7 +2,6 @@ import re
import pytest import pytest
from ytdl_sub.script.parser import BRACKET_NOT_CLOSED
from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT
from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT
from ytdl_sub.script.parser import ArgumentParser from ytdl_sub.script.parser import ArgumentParser

View file

@ -0,0 +1,62 @@
import re
from typing import Tuple
import pytest
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
from ytdl_sub.script.parser import UNEXPECTED_CHAR_ARGUMENT
from ytdl_sub.script.parser import UNEXPECTED_COMMA_ARGUMENT
from ytdl_sub.script.parser import ArgumentParser
from ytdl_sub.script.script import Script
from ytdl_sub.script.types.array import ResolvedArray
from ytdl_sub.script.types.resolvable import Float
from ytdl_sub.script.types.resolvable import Integer
from ytdl_sub.script.types.resolvable import String
from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
class TestInteger:
@pytest.mark.parametrize(
"integer",
[
"{1}",
"{ 1 }",
"{-1}",
"{ -1 }",
"{0001}",
"{ 0001 }",
],
)
def test_integer_not_arg(self, integer: str):
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_ONLY_ARGS))):
Script({"integer": integer}).resolve()
@pytest.mark.parametrize(
"integer, expected_integer",
[
("{%int(1)}", 1),
("{%int( 1 )}", 1),
("{%int(-1)}", -1),
("{%int( -1 )}", -1),
("{%int(0001)}", 1),
("{%int( 0001 )}", 1),
],
)
def test_integer(self, integer: str, expected_integer: int):
assert Script({"integer": integer}).resolve() == {"integer": Integer(expected_integer)}
@pytest.mark.parametrize(
"integer",
[
"{%add(0, --1)}",
"{%add(0, 1- )}",
"{%add(0,-1-)}",
"{%add(0, -1 - )}",
"{%add(0,0001a)}",
"{%add(0, 0001b )}",
],
)
def test_invalid_integer(self, integer: str):
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_INVALID_CHAR))):
Script({"integer": integer}).resolve()