From d80a63631ac3c48a03d8c69684e22ba5081b725c Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sun, 7 Jan 2024 00:13:32 -0800 Subject: [PATCH] [BACKEND] String `split` scripting function (#877) --- .../scripting/scripting_functions.rst | 7 +++++++ .../script/functions/string_functions.py | 17 +++++++++++++++ .../script/functions/test_string_functions.py | 21 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/docs/source/config_reference/scripting/scripting_functions.rst b/docs/source/config_reference/scripting/scripting_functions.rst index 04dbbb49..1e62d137 100644 --- a/docs/source/config_reference/scripting/scripting_functions.rst +++ b/docs/source/config_reference/scripting/scripting_functions.rst @@ -565,6 +565,13 @@ slice :description: Returns the slice of the Array. +split +~~~~~ +:spec: ``split(string: String, sep: String, max_split: Optional[Integer]) -> Array`` + +:description: + Splits the input string into multiple strings. + string ~~~~~~ :spec: ``string(value: AnyArgument) -> String`` diff --git a/src/ytdl_sub/script/functions/string_functions.py b/src/ytdl_sub/script/functions/string_functions.py index 1f0280b5..fd0cac9f 100644 --- a/src/ytdl_sub/script/functions/string_functions.py +++ b/src/ytdl_sub/script/functions/string_functions.py @@ -1,5 +1,6 @@ from typing import Optional +from ytdl_sub.script.types.array import Array from ytdl_sub.script.types.resolvable import AnyArgument from ytdl_sub.script.types.resolvable import Boolean from ytdl_sub.script.types.resolvable import Integer @@ -80,6 +81,22 @@ class StringFunctions: return String(string.value.replace(old.value, new.value)) + @staticmethod + def split(string: String, sep: String, max_split: Optional[Integer] = None) -> Array: + """ + :description: + Splits the input string into multiple strings. + """ + if max_split is not None: + return Array( + [ + String(split_val) + for split_val in string.value.split(sep=sep.value, maxsplit=max_split.value) + ] + ) + + return Array([String(split_val) for split_val in string.value.split(sep=sep.value)]) + @staticmethod def concat(*values: String) -> String: """ diff --git a/tests/unit/script/functions/test_string_functions.py b/tests/unit/script/functions/test_string_functions.py index 9a48079a..cfa5175e 100644 --- a/tests/unit/script/functions/test_string_functions.py +++ b/tests/unit/script/functions/test_string_functions.py @@ -1,3 +1,6 @@ +from typing import List +from typing import Optional + import pytest from unit.script.conftest import single_variable_output @@ -114,3 +117,21 @@ class TestNumericFunctions: def test_contains(self, value, expected_output): output = single_variable_output(f"{{%contains('a brown dog', '{value}')}}") assert output == expected_output + + @pytest.mark.parametrize( + "input_string, split, max_split, expected_output", + [ + ("no splits", " | ", None, ["no splits"]), + ("one | split", " | ", None, ["one", "split"]), + ("max | split | one", " | ", 1, ["max", "split | one"]), + ], + ) + def test_split( + self, input_string: str, split: str, max_split: Optional[int], expected_output: List[str] + ): + if max_split: + output = single_variable_output(f"{{%split('{input_string}', '{split}', {max_split})}}") + else: + output = single_variable_output(f"{{%split('{input_string}', '{split}')}}") + + assert output == expected_output