function argument, no more ytdl-sub errors!
This commit is contained in:
parent
03dcc73a71
commit
79d9be3f23
5 changed files with 39 additions and 12 deletions
|
|
@ -25,13 +25,12 @@ from ytdl_sub.script.utils.exceptions import UNREACHABLE
|
||||||
from ytdl_sub.script.utils.exceptions import CycleDetected
|
from ytdl_sub.script.utils.exceptions import CycleDetected
|
||||||
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist
|
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist
|
||||||
from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
|
from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
|
||||||
|
from ytdl_sub.script.utils.exceptions import InvalidCustomFunctionArgumentName
|
||||||
from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
|
from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
|
||||||
from ytdl_sub.script.utils.exceptions import InvalidVariableName
|
from ytdl_sub.script.utils.exceptions import InvalidVariableName
|
||||||
from ytdl_sub.script.utils.exceptions import UserException
|
from ytdl_sub.script.utils.exceptions import UserException
|
||||||
from ytdl_sub.script.utils.exceptions import VariableDoesNotExist
|
from ytdl_sub.script.utils.exceptions import VariableDoesNotExist
|
||||||
from ytdl_sub.script.utils.name_validation import validate_variable_name
|
from ytdl_sub.script.utils.name_validation import validate_variable_name
|
||||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
|
||||||
from ytdl_sub.validators.string_formatter_validators import is_valid_source_variable_name
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
|
|
@ -197,6 +196,7 @@ class _Parser:
|
||||||
Begin parsing function args after the first ``$``, i.e. ``$0``
|
Begin parsing function args after the first ``$``, i.e. ``$0``
|
||||||
"""
|
"""
|
||||||
var_name = ""
|
var_name = ""
|
||||||
|
variable_start_pos = self._pos
|
||||||
while ch := self._read(increment_pos=False):
|
while ch := self._read(increment_pos=False):
|
||||||
if ch.isspace() and not var_name:
|
if ch.isspace() and not var_name:
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
|
|
@ -204,15 +204,14 @@ class _Parser:
|
||||||
if _is_breakable(ch):
|
if _is_breakable(ch):
|
||||||
break
|
break
|
||||||
|
|
||||||
is_numeric = ch.isnumeric()
|
|
||||||
if not is_numeric:
|
|
||||||
raise StringFormattingException("invalid function var name")
|
|
||||||
|
|
||||||
var_name += ch
|
var_name += ch
|
||||||
self._pos += 1
|
self._pos += 1
|
||||||
|
|
||||||
if not var_name:
|
if not var_name.isnumeric():
|
||||||
raise StringFormattingException("invalid var name")
|
self._set_highlight_position(variable_start_pos)
|
||||||
|
raise InvalidCustomFunctionArgumentName(
|
||||||
|
"Custom function arguments must be numeric and increment starting from zero."
|
||||||
|
)
|
||||||
|
|
||||||
return FunctionArgument.from_idx(idx=int(var_name), custom_function_name=self._name)
|
return FunctionArgument.from_idx(idx=int(var_name), custom_function_name=self._name)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ class InvalidFunctionName(UserException):
|
||||||
"""Custom function name is invalid"""
|
"""Custom function name is invalid"""
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidCustomFunctionArgumentName(UserException):
|
||||||
|
"""Custom function argument name (i.e. $0) is invalid"""
|
||||||
|
|
||||||
|
|
||||||
class IncompatibleFunctionArguments(UserException):
|
class IncompatibleFunctionArguments(UserException):
|
||||||
"""Function has invalid arguments"""
|
"""Function has invalid arguments"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from ytdl_sub.script.types.array import ResolvedArray
|
||||||
from ytdl_sub.script.types.resolvable import Integer
|
from ytdl_sub.script.types.resolvable import Integer
|
||||||
from ytdl_sub.script.utils.exceptions import CycleDetected
|
from ytdl_sub.script.utils.exceptions import CycleDetected
|
||||||
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist
|
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist
|
||||||
|
from ytdl_sub.script.utils.exceptions import InvalidCustomFunctionArgumentName
|
||||||
|
|
||||||
|
|
||||||
class TestCustomFunction:
|
class TestCustomFunction:
|
||||||
|
|
@ -80,3 +81,26 @@ class TestCustomFunction:
|
||||||
"output": "{%func(1)}",
|
"output": "{%func(1)}",
|
||||||
}
|
}
|
||||||
).resolve()
|
).resolve()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"name",
|
||||||
|
[
|
||||||
|
"$00invalid",
|
||||||
|
"$abc",
|
||||||
|
"$3.14",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_custom_function_invalid_function_arguments(self, name: str):
|
||||||
|
with pytest.raises(
|
||||||
|
InvalidCustomFunctionArgumentName,
|
||||||
|
match=re.escape(
|
||||||
|
"Custom function arguments must be numeric and increment starting from zero."
|
||||||
|
),
|
||||||
|
):
|
||||||
|
Script(
|
||||||
|
{
|
||||||
|
"%func1": f"{{%mul(1, {name})}}",
|
||||||
|
"%func0": "{%mul(%func1(1), $0)}",
|
||||||
|
"output": "{%func0(1)}",
|
||||||
|
}
|
||||||
|
).resolve()
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class TestFloat:
|
||||||
)
|
)
|
||||||
def test_float_not_arg(self, integer: str):
|
def test_float_not_arg(self, integer: str):
|
||||||
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_ONLY_ARGS))):
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_ONLY_ARGS))):
|
||||||
Script({"float": integer}).resolve()
|
Script({"out": integer}).resolve()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"float_, expected_float",
|
"float_, expected_float",
|
||||||
|
|
@ -57,7 +57,7 @@ class TestFloat:
|
||||||
)
|
)
|
||||||
def test_invalid_float(self, float_: str):
|
def test_invalid_float(self, float_: str):
|
||||||
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_INVALID_CHAR))):
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(NUMERICS_INVALID_CHAR))):
|
||||||
Script({"float": float_}).resolve()
|
Script({"out": float_}).resolve()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"to_cast, expected_float",
|
"to_cast, expected_float",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class TestString:
|
||||||
)
|
)
|
||||||
def test_string_not_arg(self, string: str):
|
def test_string_not_arg(self, string: str):
|
||||||
with pytest.raises(InvalidSyntaxException, match=re.escape(str(STRINGS_ONLY_ARGS))):
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(STRINGS_ONLY_ARGS))):
|
||||||
Script({"string": string}).resolve()
|
Script({"out": string}).resolve()
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"string, expected_string",
|
"string, expected_string",
|
||||||
|
|
@ -59,4 +59,4 @@ class TestString:
|
||||||
)
|
)
|
||||||
def test_string_not_closed_properly(self, string: str):
|
def test_string_not_closed_properly(self, string: str):
|
||||||
with pytest.raises(InvalidSyntaxException, match=re.escape(str(STRINGS_NOT_CLOSED))):
|
with pytest.raises(InvalidSyntaxException, match=re.escape(str(STRINGS_NOT_CLOSED))):
|
||||||
Script({"string": string}).resolve()
|
Script({"out": string}).resolve()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue