From d50c0c6559276642989f4d9954148b60609f21ba Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 13 Nov 2023 23:00:29 -0800 Subject: [PATCH] string, bool, function tests wip --- src/ytdl_sub/script/parser.py | 14 ++++++++-- tests/unit/script/types/test_bool.py | 20 ++++++++++++++ tests/unit/script/types/test_function.py | 20 ++++++++++++++ tests/unit/script/types/test_string.py | 33 ++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 tests/unit/script/types/test_bool.py create mode 100644 tests/unit/script/types/test_function.py create mode 100644 tests/unit/script/types/test_string.py diff --git a/src/ytdl_sub/script/parser.py b/src/ytdl_sub/script/parser.py index d00a9488..44036228 100644 --- a/src/ytdl_sub/script/parser.py +++ b/src/ytdl_sub/script/parser.py @@ -47,6 +47,10 @@ NUMERICS_ONLY_ARGS = InvalidSyntaxException( NUMERICS_INVALID_CHAR = InvalidSyntaxException("Invalid value when parsing a numeric") +STRINGS_ONLY_ARGS = InvalidSyntaxException( + "Strings can only be used as arguments to functions, maps, or arrays" +) + def UNEXPECTED_CHAR_ARGUMENT(parser: ArgumentParser): return InvalidSyntaxException(f"Unexpected character when parsing {parser.value} arguments") @@ -72,6 +76,8 @@ def _is_variable_start(char: str) -> bool: def _is_numeric_start(char: str) -> bool: return char.isnumeric() or char == "-" +def _is_string_start(char: str) -> bool: + return char in ["'", '"'] def _is_breakable(char: str) -> bool: return char in ["}", ",", ")", "]"] or char.isspace() @@ -214,7 +220,9 @@ class _Parser: """ string_value = "" open_quotation_char = self._read() - assert open_quotation_char in ["'", '"'] + + if not _is_string_start(open_quotation_char): + raise UNREACHABLE while ch := self._read(): if ch == open_quotation_char: @@ -235,7 +243,7 @@ class _Parser: if (self._read(increment_pos=False, length=5) or "").lower() == "false": self._pos += 5 return Boolean(value=False) - if self._read(increment_pos=False) in ["'", '"']: + if _is_string_start(self._read(increment_pos=False)): return self._parse_string() if self._read(increment_pos=False) == "[": self._pos += 1 @@ -416,6 +424,8 @@ class _Parser: self._ast.append(self._parse_variable()) elif _is_numeric_start(ch1): raise NUMERICS_ONLY_ARGS + elif _is_string_start(ch1): + raise STRINGS_ONLY_ARGS else: raise UNEXPECTED_CHAR_ARGUMENT(parser=ArgumentParser.SCRIPT) elif bracket_counter == 0: diff --git a/tests/unit/script/types/test_bool.py b/tests/unit/script/types/test_bool.py new file mode 100644 index 00000000..d89c8278 --- /dev/null +++ b/tests/unit/script/types/test_bool.py @@ -0,0 +1,20 @@ +import re +from typing import Tuple + +import pytest + +from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS +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 TestBool: + pass \ No newline at end of file diff --git a/tests/unit/script/types/test_function.py b/tests/unit/script/types/test_function.py new file mode 100644 index 00000000..d1b71f9c --- /dev/null +++ b/tests/unit/script/types/test_function.py @@ -0,0 +1,20 @@ +import re +from typing import Tuple + +import pytest + +from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS +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 TestFunction: + pass \ No newline at end of file diff --git a/tests/unit/script/types/test_string.py b/tests/unit/script/types/test_string.py new file mode 100644 index 00000000..2c155b7e --- /dev/null +++ b/tests/unit/script/types/test_string.py @@ -0,0 +1,33 @@ +import re +from typing import Tuple + +import pytest + +from ytdl_sub.script.parser import NUMERICS_INVALID_CHAR, STRINGS_ONLY_ARGS +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 TestString: + @pytest.mark.parametrize( + "string", + [ + "{'323'}", + "{ \"4253\" }", + "{\"hi\"}", + "{ \"asfsd\" }", + "{\"sdfasf\"}", + "{ '3fsdf' }", + ], + ) + def test_string_not_arg(self, string: str): + with pytest.raises(InvalidSyntaxException, match=re.escape(str(STRINGS_ONLY_ARGS))): + Script({"string": string}).resolve()