bool tests

This commit is contained in:
Jesse Bannon 2023-11-14 20:00:08 -08:00
parent f7f8502c8e
commit c6173ec14b
7 changed files with 67 additions and 11 deletions

View file

@ -1,11 +1,17 @@
from typing import Optional
from ytdl_sub.script.functions.array_functions import ArrayFunctions from ytdl_sub.script.functions.array_functions import ArrayFunctions
from ytdl_sub.script.functions.boolean_functions import BooleanFunctions
from ytdl_sub.script.functions.map_functions import MapFunctions from ytdl_sub.script.functions.map_functions import MapFunctions
from ytdl_sub.script.functions.numeric_functions import NumericFunctions from ytdl_sub.script.functions.numeric_functions import NumericFunctions
from ytdl_sub.script.functions.special_functions import SpecialFunctions from ytdl_sub.script.functions.special_functions import SpecialFunctions
from ytdl_sub.script.functions.string_functions import StringFunctions from ytdl_sub.script.functions.string_functions import StringFunctions
class Functions(StringFunctions, NumericFunctions, SpecialFunctions, ArrayFunctions, MapFunctions): class Functions(
StringFunctions,
NumericFunctions,
SpecialFunctions,
ArrayFunctions,
MapFunctions,
BooleanFunctions,
):
pass pass

View file

@ -55,6 +55,10 @@ STRINGS_NOT_CLOSED = InvalidSyntaxException(
"Must open and close with the same type of quote (single/double)" "Must open and close with the same type of quote (single/double)"
) )
BOOLEAN_ONLY_ARGS = InvalidSyntaxException(
"Booleans can only be used as arguments to functions, maps, or arrays"
)
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")
@ -90,6 +94,14 @@ def _is_breakable(char: str) -> bool:
return char in ["}", ",", ")", "]"] or char.isspace() return char in ["}", ",", ")", "]"] or char.isspace()
def _is_boolean_true(string: Optional[str]) -> bool:
return string == "True"
def _is_boolean_false(string: Optional[str]) -> bool:
return string == "False"
class _Parser: class _Parser:
def __init__(self, text: str): def __init__(self, text: str):
self._text = text self._text = text
@ -252,10 +264,10 @@ class _Parser:
return self._parse_function() return self._parse_function()
if _is_numeric_start(self._read(increment_pos=False)): 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 _is_boolean_true(self._read(increment_pos=False, length=4)):
self._pos += 4 self._pos += 4
return Boolean(value=True) return Boolean(value=True)
if (self._read(increment_pos=False, length=5) or "").lower() == "false": if _is_boolean_false(self._read(increment_pos=False, length=5)):
self._pos += 5 self._pos += 5
return Boolean(value=False) return Boolean(value=False)
if _is_string_start(self._read(increment_pos=False)): if _is_string_start(self._read(increment_pos=False)):
@ -441,6 +453,10 @@ class _Parser:
raise NUMERICS_ONLY_ARGS raise NUMERICS_ONLY_ARGS
elif _is_string_start(ch1): elif _is_string_start(ch1):
raise STRINGS_ONLY_ARGS raise STRINGS_ONLY_ARGS
elif _is_boolean_true(
self._read(increment_pos=False, length=4)
) or _is_boolean_false(self._read(increment_pos=False, length=5)):
raise BOOLEAN_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

@ -155,7 +155,7 @@ class TestParser:
input_str = ( input_str = (
f"hello{s}{{{s}%concat({s}'string'{s},{s}%string(1){s},{s}%string(2.4){s}," f"hello{s}{{{s}%concat({s}'string'{s},{s}%string(1){s},{s}%string(2.4){s},"
f"{s}%string(TRUE){s},{s}%string(variable_name){s},{s}%capitalize({s}'hi'{s}){s})}}" f"{s}%string(True){s},{s}%string(variable_name){s},{s}%capitalize({s}'hi'{s}){s})}}"
f"{s}" f"{s}"
) )
parsed = parse(input_str) parsed = parse(input_str)

View file

@ -3,14 +3,15 @@ from typing import Tuple
import pytest import pytest
from ytdl_sub.script.parser import BOOLEAN_ONLY_ARGS
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
from ytdl_sub.script.parser import STRINGS_ONLY_ARGS
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
from ytdl_sub.script.script import Script from ytdl_sub.script.script import Script
from ytdl_sub.script.types.array import ResolvedArray from ytdl_sub.script.types.array import ResolvedArray
from ytdl_sub.script.types.resolvable import Boolean
from ytdl_sub.script.types.resolvable import Float from ytdl_sub.script.types.resolvable import Float
from ytdl_sub.script.types.resolvable import Integer from ytdl_sub.script.types.resolvable import Integer
from ytdl_sub.script.types.resolvable import String from ytdl_sub.script.types.resolvable import String
@ -18,4 +19,30 @@ from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
class TestBool: class TestBool:
pass @pytest.mark.parametrize(
"boolean",
[
"{True}",
"{ True }",
"{False}",
"{ False }",
],
)
def test_boolean_not_arg(self, boolean: str):
with pytest.raises(InvalidSyntaxException, match=re.escape(str(BOOLEAN_ONLY_ARGS))):
Script({"boolean": boolean}).resolve()
@pytest.mark.parametrize(
"boolean, expected_boolean",
[
("{%bool(True)}", True),
("{%bool(False)}", False),
("{%bool( True )}", True),
("{%bool( False )}", False),
],
)
def test_boolean(self, boolean: bool, expected_boolean: bool):
assert Script({"boolean": boolean, "as_string": "{%string(boolean)}"}).resolve() == {
"boolean": Boolean(expected_boolean),
"as_string": String(str(expected_boolean)),
}

View file

@ -44,7 +44,10 @@ class TestFloat:
], ],
) )
def test_float(self, float_: str, expected_float: int): def test_float(self, float_: str, expected_float: int):
assert Script({"float": float_}).resolve() == {"float": Float(expected_float)} assert Script({"float": float_, "as_string": "{%string(float)}"}).resolve() == {
"float": Float(expected_float),
"as_string": String(str(expected_float)),
}
@pytest.mark.parametrize( @pytest.mark.parametrize(
"float_", "float_",

View file

@ -44,7 +44,10 @@ class TestInteger:
], ],
) )
def test_integer(self, integer: str, expected_integer: int): def test_integer(self, integer: str, expected_integer: int):
assert Script({"integer": integer}).resolve() == {"integer": Integer(expected_integer)} assert Script({"integer": integer, "as_string": "{%string(integer)}"}).resolve() == {
"integer": Integer(expected_integer),
"as_string": String(str(expected_integer)),
}
@pytest.mark.parametrize( @pytest.mark.parametrize(
"integer", "integer",

View file

@ -3,8 +3,9 @@ from typing import Tuple
import pytest import pytest
from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_NOT_CLOSED from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR
from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS from ytdl_sub.script.parser import NUMERICS_ONLY_ARGS
from ytdl_sub.script.parser import STRINGS_NOT_CLOSED
from ytdl_sub.script.parser import STRINGS_ONLY_ARGS from ytdl_sub.script.parser import STRINGS_ONLY_ARGS
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