tool functions and pytest

This commit is contained in:
2025-01-01 18:20:50 +01:00
parent 823f13ab51
commit fd7e3d5235
10 changed files with 406 additions and 108 deletions

1
tests/__init__.py Normal file
View File

@@ -0,0 +1 @@
# empty

7
tests/helper.py Normal file
View File

@@ -0,0 +1,7 @@
def tool_dummy(a: int, b: str):
return "result_%d_%s" % (a, b)
def tool_dummy2(text: str):
return text.upper()

View File

@@ -0,0 +1,30 @@
import pytest
import tool_helper
import tests.helper as helper
def test_tool_function_decorator_if_clean_tool_list():
""" tests for the tool list to be empty. NOT strictly nessesary,
but I want to be warned if this is not the case anymore. Could be not the intention """
start_len = len(tool_helper.tool_list)
assert start_len == 0
def test_tool_function_decorator():
# get length before adding tools
start_len = len(tool_helper.tool_list)
# add tools like it would be a decorator
tool_helper.tool(helper.tool_dummy)
tool_helper.tool(helper.tool_dummy2)
# get length after adding tools
end_len = len(tool_helper.tool_list)
# remove the added ones again
tool_helper.tool_list = tool_helper.tool_list[:-2]
assert end_len == start_len + 2
assert len(tool_helper.tool_list) == start_len

View File

@@ -0,0 +1,89 @@
import pytest
import tool_helper
from unittest import mock
import tests.helper as helper
def test_tool_dummy():
with mock.patch("tests.helper.tool_dummy") as mock_dummy:
helper.tool_dummy()
mock_dummy.assert_called_once() # this will check if the mocked function on the context was called.
def test_tool_parse_no_exec():
with mock.patch("tests.helper.tool_dummy") as mock_dummy:
tool_helper.parse_and_execute_tool_call("something else", [helper.tool_dummy, helper.tool_dummy2])
assert mock_dummy.call_count == 0
def test_match_and_extract_no_match():
result = tool_helper._match_and_extract("something else", r"<tool_call>(.*)<\/tool_call>")
assert result == None
def test_match_and_extract_matching():
result = tool_helper._match_and_extract("asdfsdfas <tool_call>{json content}</tool_call> adfafsd", r"<tool_call>(.*)<\/tool_call>")
assert result == "{json content}"
def test_match_and_extract_matching2():
result = tool_helper._match_and_extract("<tool_call>{json content}</tool_call>", r"<tool_call>(.*)<\/tool_call>")
assert result == "{json content}"
def test_match_and_extract_matching3_with_newline():
result = tool_helper._match_and_extract("<tool_call>\n{json content}\n</tool_call>", r"<tool_call>(.*)<\/tool_call>")
assert result == "\n{json content}\n"
def test_string_malformed_faulty():
with mock.patch("utils.print_error") as print_error_mock:
result = tool_helper._execute_tool_call_str("{json_content}", [])
assert result == None
print_error_mock.assert_called_once() # this will check if the mocked function on the context was called.
def test_tool_call_json_1():
with mock.patch("utils.print_error") as print_error_mock:
result = tool_helper._execute_tool_call_json({"name": "tool_dummy", "arguments": {"a": 1, "b": "zwei"}}, [helper.tool_dummy, helper.tool_dummy2])
assert result == "result_1_zwei"
assert print_error_mock.call_count == 0
def test_tool_call_json_2():
with mock.patch("utils.print_error") as print_error_mock:
result = tool_helper._execute_tool_call_json({"name": "tool_dummy2", "arguments": {"text": "some_text"}}, [helper.tool_dummy, helper.tool_dummy2])
assert result == "SOME_TEXT"
assert print_error_mock.call_count == 0
def test_tool_call_json_non_existing_call_check():
with mock.patch("utils.print_error") as print_error_mock:
result = tool_helper._execute_tool_call_json({"name": "tool_dummy_which_is_not_existing", "arguments": {"text": "some_text"}}, [helper.tool_dummy, helper.tool_dummy2])
assert result == None
assert print_error_mock.call_count == 1 # this will check if the mocked function on the context was called.
def test_tool_call_json_wrong_arguments_check():
with mock.patch("utils.print_error") as print_error_mock:
result = tool_helper._execute_tool_call_json({"name": "tool_dummy", "arguments": {"a": "must_be_an_int_but_is_string", "b": "zwei"}}, [helper.tool_dummy, helper.tool_dummy2])
assert result == None
assert print_error_mock.call_count == 1 # this will check if the mocked function on the context was called.
def test_regex_multiline():
import re
pattern = r"<start>(.*)</end>"
# The text to search (spanning multiple lines)
text = """<start>
{json}
</end>"""
# Use re.search with re.DOTALL to match across newlines
match = re.search(pattern, text, re.DOTALL)
assert match.group(1).find("{json}") != -1