summaryrefslogtreecommitdiff
path: root/src/extension_loader.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension_loader.zig')
-rw-r--r--src/extension_loader.zig49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/extension_loader.zig b/src/extension_loader.zig
index b84eba5..6d470cc 100644
--- a/src/extension_loader.zig
+++ b/src/extension_loader.zig
@@ -491,6 +491,27 @@ fn applyShadowing(allocator: Allocator, list: *std.array_list.Managed(Found)) !v
const testing = std.testing;
+/// Test helper: first text part of a tool result.
+fn xokText(result: panto.ToolCallResult) []const u8 {
+ switch (result) {
+ .ok => |parts| {
+ for (parts) |p| {
+ if (p == .text) return p.text;
+ }
+ return "";
+ },
+ .err => return "",
+ }
+}
+
+/// Test helper: free a results slice (parts on `.ok`).
+fn xfreeResults(results: []panto.ToolCallResult) void {
+ for (results) |r| switch (r) {
+ .ok => |b| panto.freeResultParts(testing.allocator, b),
+ .err => {},
+ };
+}
+
fn writeFile(dir: Io.Dir, sub_path: []const u8, content: []const u8) !void {
try dir.writeFile(testing.io, .{ .sub_path = sub_path, .data = content });
}
@@ -643,8 +664,8 @@ test "loadFromDirs: project shadows user end-to-end (via long-lived runtime)" {
const calls = [_]panto.ToolCall{.{ .tool_name = "greet", .input = "{}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("PROJECT", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("PROJECT", xokText(results[0]));
}
test "loadFromDirs: tool-name collision between extensions errors" {
@@ -711,8 +732,8 @@ test "loadFromDirs: tools/ directory — single-file tool form" {
const calls = [_]panto.ToolCall{.{ .tool_name = "echo", .input = "{\"msg\":\"hi\"}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("echo: hi", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("echo: hi", xokText(results[0]));
}
test "loadFromDirs: tools/ directory — directory-style tool with sibling require" {
@@ -751,8 +772,8 @@ test "loadFromDirs: tools/ directory — directory-style tool with sibling requi
const calls = [_]panto.ToolCall{.{ .tool_name = "shout", .input = "{\"text\":\"hi\"}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("HI!", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("HI!", xokText(results[0]));
}
test "loadFromDirs: project tool shadows user tool of the same name" {
@@ -799,8 +820,8 @@ test "loadFromDirs: project tool shadows user tool of the same name" {
const calls = [_]panto.ToolCall{.{ .tool_name = "greet", .input = "{}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("PROJECT", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("PROJECT", xokText(results[0]));
}
test "loadFromDirs: project tool shadows user shadows base" {
@@ -858,8 +879,8 @@ test "loadFromDirs: project tool shadows user shadows base" {
const calls = [_]panto.ToolCall{.{ .tool_name = "greet", .input = "{}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("PROJECT", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("PROJECT", xokText(results[0]));
}
test "loadFromDirs: user tool shadows base tool when no project entry" {
@@ -905,8 +926,8 @@ test "loadFromDirs: user tool shadows base tool when no project entry" {
const calls = [_]panto.ToolCall{.{ .tool_name = "greet", .input = "{}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("USER", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("USER", xokText(results[0]));
}
test "loadFromDirs: extension and tool share a *file* name independently" {
@@ -996,8 +1017,8 @@ test "loadFromDirs: tools policy removes a denied registered tool name" {
const calls = [_]panto.ToolCall{.{ .tool_name = "std.read", .input = "{}" }};
var results: [1]panto.ToolCallResult = .{.{ .err = error.SourceDroppedCall }};
try src.vtable.invoke_batch(src.ctx, &calls, &results, testing.allocator);
- defer testing.allocator.free(results[0].ok);
- try testing.expectEqualStrings("READ", results[0].ok);
+ defer xfreeResults(&results);
+ try testing.expectEqualStrings("READ", xokText(results[0]));
}
test "loadFromDirs: extensions policy denies a whole entry before it loads" {