int tests WIP
This commit is contained in:
parent
7f0ccd5f3c
commit
b86ff252e5
3 changed files with 99 additions and 6 deletions
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
62
tests/unit/script/types/test_integer.py
Normal file
62
tests/unit/script/types/test_integer.py
Normal 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()
|
||||||
Loading…
Reference in a new issue