190 lines
6.2 KiB
Python
190 lines
6.2 KiB
Python
import atexit
|
|
import importlib
|
|
import shutil
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
TEST_RUNTIME_DIR = PROJECT_ROOT / ".test-runtime"
|
|
atexit.register(lambda: shutil.rmtree(TEST_RUNTIME_DIR, ignore_errors=True))
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
with patch("os.getcwd", return_value=str(TEST_RUNTIME_DIR)):
|
|
nodes = importlib.import_module("nodes")
|
|
|
|
|
|
class SetVariableNodeTests(unittest.TestCase):
|
|
def test_unset_value_is_stored_as_empty_string(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariable()
|
|
|
|
with patch.object(nodes, "get_prompt_generator") as get_prompt_generator:
|
|
result = node.set_variable("name", None, "", seed=1)
|
|
|
|
get_prompt_generator.assert_not_called()
|
|
self.assertEqual(result, ({"name": ""}, True))
|
|
|
|
def test_empty_value_does_not_call_dynamic_prompt_generator(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariable()
|
|
|
|
with patch.object(nodes, "get_prompt_generator") as get_prompt_generator:
|
|
result = node.set_variable("name", "", "", seed=1)
|
|
|
|
get_prompt_generator.assert_not_called()
|
|
self.assertEqual(result, ({"name": ""}, True))
|
|
|
|
def test_empty_value_can_be_applied_to_prompt(self):
|
|
prompt = nodes.apply_vars("Hello<$name>", {"name": ""})
|
|
|
|
self.assertEqual(prompt, "Hello<>")
|
|
|
|
def test_trim_removes_surrounding_whitespace_before_storing_value(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariable()
|
|
|
|
result = node.set_variable("name", "\n Ada Lovelace \t", "", seed=1, trim=True)
|
|
|
|
self.assertEqual(result, ({"name": "Ada Lovelace"}, True))
|
|
|
|
def test_trim_false_preserves_surrounding_whitespace(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariable()
|
|
|
|
result = node.set_variable("name", "\n Ada Lovelace \t", "", seed=1)
|
|
|
|
self.assertEqual(result, ({"name": "\n Ada Lovelace \t"}, True))
|
|
|
|
def test_trim_is_applied_after_variable_replacement(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariable()
|
|
|
|
result = node.set_variable(
|
|
"greeting",
|
|
" $name ",
|
|
"",
|
|
seed=1,
|
|
trim=True,
|
|
vars={"name": "Ada"},
|
|
)
|
|
|
|
self.assertEqual(result, ({"name": "Ada", "greeting": "Ada"}, True))
|
|
|
|
|
|
class SetVariableByChoiceNodeTests(unittest.TestCase):
|
|
def test_sets_variable_from_matching_source_value(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
generator = unittest.mock.Mock()
|
|
generator.generate.return_value = ["John"]
|
|
|
|
with patch.object(nodes, "get_prompt_generator", return_value=generator):
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"gender",
|
|
'"male": "{John|Bill|Ted}", "female": "{Anna|Sarah|Sofia}"',
|
|
seed=7,
|
|
vars={"gender": "male"},
|
|
)
|
|
|
|
generator.generate.assert_called_once_with(
|
|
"{John|Bill|Ted}",
|
|
1,
|
|
seeds=7,
|
|
)
|
|
self.assertEqual(result, ({"gender": "male", "name": "John"}, True))
|
|
|
|
def test_source_variable_can_include_dollar_prefix(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"$gender",
|
|
'{"female": "Anna"}',
|
|
seed=1,
|
|
vars={"gender": "female"},
|
|
)
|
|
|
|
self.assertEqual(result, ({"gender": "female", "name": "Anna"}, True))
|
|
|
|
def test_choice_value_can_use_existing_variables(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"gender",
|
|
'{"female": "$prefix Anna"}',
|
|
seed=1,
|
|
vars={"gender": "female", "prefix": "Dr."},
|
|
)
|
|
|
|
self.assertEqual(
|
|
result,
|
|
({"gender": "female", "prefix": "Dr.", "name": "Dr. Anna"}, True),
|
|
)
|
|
|
|
def test_missing_choice_does_not_update_vars(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"gender",
|
|
'{"female": "Anna"}',
|
|
seed=1,
|
|
vars={"gender": "male"},
|
|
)
|
|
|
|
self.assertEqual(result, ({"gender": "male"}, False))
|
|
|
|
def test_default_choice_is_used_when_no_exact_match_exists(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"gender",
|
|
'{"__default__": "Alex"}',
|
|
seed=1,
|
|
vars={"gender": "unknown"},
|
|
)
|
|
|
|
self.assertEqual(result, ({"gender": "unknown", "name": "Alex"}, True))
|
|
|
|
def test_trim_removes_surrounding_whitespace_from_choice_value(self):
|
|
node = nodes.ArtemKo7vComplexPromptSetVariableByChoice()
|
|
|
|
result = node.set_variable_by_choice(
|
|
"name",
|
|
"gender",
|
|
'{"female": " Anna\\n"}',
|
|
seed=1,
|
|
trim=True,
|
|
vars={"gender": "female"},
|
|
)
|
|
|
|
self.assertEqual(result, ({"gender": "female", "name": "Anna"}, True))
|
|
|
|
|
|
class ComplexPromptNodeTests(unittest.TestCase):
|
|
def test_plain_text_with_variable_does_not_call_dynamic_prompt_generator(self):
|
|
node = nodes.ArtemKo7vComplexPrompt()
|
|
|
|
with patch.object(nodes, "get_prompt_generator") as get_prompt_generator:
|
|
result = node.generate_prompt(
|
|
"test $anyvar test",
|
|
seed=1,
|
|
vars={"anyvar": ""},
|
|
)
|
|
|
|
get_prompt_generator.assert_not_called()
|
|
self.assertEqual(result, ("test test",))
|
|
|
|
def test_dynamic_prompt_syntax_still_calls_generator(self):
|
|
generator = unittest.mock.Mock()
|
|
generator.generate.return_value = ["test red $anyvar"]
|
|
|
|
with patch.object(nodes, "get_prompt_generator", return_value=generator):
|
|
result = nodes.generate_dynamic_prompt("test {red|blue} $anyvar", seed=5)
|
|
|
|
generator.generate.assert_called_once()
|
|
self.assertEqual(result, "test red $anyvar")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|