Files
docker-agent/pkg/tools/codemode/exec_test.go
T
Djordje Lukic e8f6745b02 refactor(tools): replace context-smuggled emitters with explicit tools.Runtime handle
Tool handlers previously reached back into the runtime through two
context keys (ToolOutputEmitter, ToolRecallEmitter), each with its own
With*/FromContext/Emit* boilerplate, invisible in the handler signature
and requiring ad-hoc lifetime tricks (context.WithoutCancel + closure
capture) for background work.

Replace both with a single tools.Runtime capability handle passed
explicitly to every handler:

- ToolHandler is now func(ctx, ToolCall, rt Runtime); runtime-managed
  handlers (toolexec.ToolHandler) grow the same parameter, unifying the
  two tool APIs on one capability surface
- Runtime methods (EmitOutput, Recall, Supports) take ctx per call and
  remain valid after the handler returns, so background jobs hold the
  handle instead of a captured closure
- NopRuntime serves hosts without an agent loop (slash commands, prompt
  expansion, tests); Supports() lets tools fail fast before starting
  background work
- NewHandler keeps its signature; NewRuntimeHandler is the variant for
  tools that talk back (shell streaming/recall, codemode forwarding)
- codemode forwards the handle into script-invoked tools, preserving
  the nested-capability inheritance the ctx transport gave implicitly
2026-07-04 09:37:25 +00:00

59 lines
1.5 KiB
Go

package codemode
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/docker/docker-agent/pkg/tools"
)
func TestRunJavascript(t *testing.T) {
t.Parallel()
tool := &codeModeTool{}
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `return "HELLO"`)
require.NoError(t, err)
assert.Equal(t, "HELLO", result.Value)
assert.Empty(t, result.StdOut)
assert.Empty(t, result.StdErr)
}
func TestRunJavascript_error(t *testing.T) {
t.Parallel()
tool := &codeModeTool{}
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `==`)
require.NoError(t, err)
assert.Equal(t, "SyntaxError: SyntaxError: (anonymous): Line 2:1 Unexpected token == (and 2 more errors)", result.Value)
assert.Empty(t, result.StdOut)
assert.Empty(t, result.StdErr)
}
func TestRunJavascript_console(t *testing.T) {
t.Parallel()
tool := &codeModeTool{}
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `console.log("to stdout"); console.error("to stderr"); return "RESULT";`)
require.NoError(t, err)
assert.Equal(t, "RESULT", result.Value)
assert.Equal(t, "to stdout\n", result.StdOut)
assert.Equal(t, "to stderr\n", result.StdErr)
}
func TestRunJavascript_no_result(t *testing.T) {
t.Parallel()
tool := &codeModeTool{}
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, ``)
require.NoError(t, err)
assert.Empty(t, result.Value)
assert.Empty(t, result.StdOut)
assert.Empty(t, result.StdErr)
}