Skip to content

Commit d7f0e34

Browse files
committed
test: wrote tests for context tool
1 parent af482a1 commit d7f0e34

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

gptme/tools/context.py

+13-11
Original file line numberDiff line numberDiff line change
@@ -37,50 +37,52 @@ def _gitignore():
3737
return ignored
3838

3939

40-
def _ctags():
40+
def _ctags() -> str:
4141
"""Generate ctags for current project."""
4242

4343
ignored = _gitignore()
4444
ignored_str = " ".join([f"--exclude='{i}'" for i in ignored])
4545

4646
shell = get_shell()
4747
cmd = f"ctags -R --output-format=json {ignored_str} --fields=+l+n --languages=python --python-kinds=-iv -f -"
48-
print(cmd)
4948
ret, ctags, _ = shell.run_command(cmd)
5049
assert ret == 0
5150

52-
print("ctags:")
51+
output = ["ctags:"]
5352
tags = []
5453
for line in ctags.splitlines():
5554
try:
5655
tags.append(json.loads(line))
5756
except json.JSONDecodeError:
58-
print(" failed to parse: ", line)
57+
output += [" failed to parse: {line}"]
5958
break
6059

6160
files = {tag["path"] for tag in tags}
6261
for file in sorted(files):
6362
filetags = [tag for tag in tags if tag["path"] == file]
64-
print(f"{file}")
63+
output += [str(file)]
6564
level = 0
6665
for tag in sorted(filetags, key=lambda x: x["line"]):
6766
if tag["kind"] == "class":
68-
print(level * " " + f" class {tag['name']}:{tag['line']}")
67+
output += [level * " " + f" class {tag['name']}:{tag['line']}"]
6968
level += 1
7069
elif tag["kind"] == "function":
7170
level = 0
72-
print(level * " " + f" def {tag['name']}:{tag['line']}")
71+
output += [level * " " + f" def {tag['name']}:{tag['line']}"]
7372
elif tag["kind"] == "variable":
7473
level = 0
75-
print(level * " " + f" {tag['name']}:{tag['line']}")
74+
output += [level * " " + f" {tag['name']}:{tag['line']}"]
7675
elif tag["kind"] == "unknown":
7776
# import a as b
7877
pass
7978
else:
80-
print(level * " " + f" {tag['kind']} {tag['name']}:{tag['line']}")
79+
output += [
80+
level * " " + f" {tag['kind']} {tag['name']}:{tag['line']}"
81+
]
8182

82-
return ctags
83+
return "\n".join(output)
8384

8485

8586
if __name__ == "__main__":
86-
assert _ctags()
87+
output = _ctags()
88+
print(output)

gptme/tools/shell.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ def __init__(self) -> None:
2323
self.stderr_fd = self.process.stderr.fileno() # type: ignore
2424
self.delimiter = "END_OF_COMMAND_OUTPUT"
2525

26+
# close on exit
27+
atexit.register(self.close)
28+
2629
def run_command(self, command: str) -> tuple[int | None, str, str]:
2730
assert self.process.stdin
2831

@@ -80,12 +83,15 @@ def get_shell() -> ShellSession:
8083
if _shell is None:
8184
# init shell
8285
_shell = ShellSession()
83-
84-
# close on exit
85-
atexit.register(_shell.close)
8686
return _shell
8787

8888

89+
# used in testing
90+
def set_shell(shell: ShellSession) -> None:
91+
global _shell
92+
_shell = shell
93+
94+
8995
def execute_shell(cmd: str, ask=True) -> Generator[Message, None, None]:
9096
"""Executes a shell command and returns the output."""
9197
shell = get_shell()

tests/test_tools_context.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
from gptme.tools.context import _ctags, _gen_context_msg
3+
from gptme.tools.shell import ShellSession, set_shell
4+
5+
6+
@pytest.fixture
7+
def shell():
8+
shell = ShellSession()
9+
set_shell(shell)
10+
return shell
11+
12+
13+
def test_gen_context_msg(shell):
14+
msg = _gen_context_msg()
15+
assert "gptme" in msg.content, f"Expected 'gptme' in output: {msg.content}"
16+
assert "$ pwd" in msg.content, f"Expected 'pwd' in output: {msg.content}"
17+
18+
19+
def test_ctags(shell):
20+
output = _ctags()
21+
assert "function" in output, f"Expected 'def' in output: {output}"

0 commit comments

Comments
 (0)