67 lines
2.0 KiB
Go
67 lines
2.0 KiB
Go
// Copyright 2026 Alibaba Group
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/executor"
|
|
)
|
|
|
|
func TestToolCallerAdapterDryRunNeverInvokesRunner(t *testing.T) {
|
|
runner := &countingErrorRunner{}
|
|
caller := newToolCallerAdapter(runner, &GlobalFlags{DryRun: true, Format: "json"})
|
|
result, err := caller.CallTool(context.Background(), "aitable-helper", "set_advanced_permission", map[string]any{"enabled": false})
|
|
if err != nil {
|
|
t.Fatalf("CallTool() error = %v", err)
|
|
}
|
|
if got := runner.calls.Load(); got != 0 {
|
|
t.Fatalf("runner calls = %d, want 0", got)
|
|
}
|
|
if result == nil || len(result.Content) != 1 || !strings.Contains(result.Content[0].Text, `"dry_run":true`) {
|
|
t.Fatalf("dry-run result = %#v", result)
|
|
}
|
|
|
|
var nilAdapter *toolCallerAdapter
|
|
if nilAdapter.DryRun() || nilAdapter.Format() != "json" {
|
|
t.Fatal("nil adapter accessors are not safe")
|
|
}
|
|
if _, err := nilAdapter.CallTool(context.Background(), "x", "y", nil); err == nil {
|
|
t.Fatal("nil adapter accepted a tool call")
|
|
}
|
|
}
|
|
|
|
func TestRuntimeRunnerGlobalDryRunStopsBeforeInjectedFallback(t *testing.T) {
|
|
fallback := &countingErrorRunner{}
|
|
runner := &runtimeRunner{globalFlags: &GlobalFlags{DryRun: true}, fallback: fallback}
|
|
result, err := runner.Run(context.Background(), executor.NewHelperInvocation(
|
|
"test",
|
|
"aitable",
|
|
"tool",
|
|
map[string]any{"id": "x"},
|
|
))
|
|
if err != nil {
|
|
t.Fatalf("Run() error = %v", err)
|
|
}
|
|
if !result.Invocation.DryRun || result.Response["dry_run"] != true {
|
|
t.Fatalf("dry-run result = %#v", result)
|
|
}
|
|
if got := fallback.calls.Load(); got != 0 {
|
|
t.Fatalf("fallback calls = %d, want 0", got)
|
|
}
|
|
}
|
|
|
|
type countingErrorRunner struct {
|
|
calls atomic.Int64
|
|
}
|
|
|
|
func (r *countingErrorRunner) Run(context.Context, executor.Invocation) (executor.Result, error) {
|
|
r.calls.Add(1)
|
|
return executor.Result{}, errors.New("runner must not be called")
|
|
}
|