Files
zzet--gortex/internal/mcp/safe_delete_propagate_test.go
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

105 lines
3.0 KiB
Go

package mcp
import (
"context"
"encoding/json"
"os"
"path/filepath"
"testing"
mcplib "github.com/mark3labs/mcp-go/mcp"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph"
"github.com/zzet/gortex/internal/indexer"
"github.com/zzet/gortex/internal/query"
)
func TestClassifyCallSite(t *testing.T) {
a, _ := classifyCallSite("\tTarget()", "Target")
require.Equal(t, "remove_line", a)
a, _ = classifyCallSite("\tobj.Target()", "Target")
require.Equal(t, "remove_line", a)
a, _ = classifyCallSite("\tx := Target()", "Target")
require.Equal(t, "manual", a)
a, _ = classifyCallSite("\treturn Target()", "Target")
require.Equal(t, "manual", a)
a, _ = classifyCallSite("\tn := a + Target()", "Target")
require.Equal(t, "manual", a)
a, _ = classifyCallSite("\tdefer Target()", "Target")
require.Equal(t, "remove_line", a)
}
func setupDeleteServer(t *testing.T) (*Server, graph.Store, string) {
t.Helper()
dir := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(dir, "del.go"), []byte(`package p
func Target() {}
`), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(dir, "caller.go"), []byte(`package p
func Caller() {
Target()
}
`), 0o644))
g := graph.New()
reg := testRegistry()
cfg := config.Default()
idx := indexer.New(g, reg, cfg.Index, zap.NewNop())
_, err := idx.Index(dir)
require.NoError(t, err)
eng := query.NewEngine(g)
srv := NewServer(eng, g, idx, nil, zap.NewNop(), nil)
srv.RunAnalysis()
return srv, g, dir
}
func TestPropagateDeletePlanAndApply(t *testing.T) {
srv, g, dir := setupDeleteServer(t)
var targetID string
for _, n := range g.AllNodes() {
if n.Name == "Target" && n.Kind == graph.KindFunction {
targetID = n.ID
}
}
require.NotEmpty(t, targetID)
callRes := func(args map[string]any) map[string]any {
req := mcplib.CallToolRequest{}
req.Params.Arguments = args
res, err := srv.handleSafeDeleteSymbol(context.Background(), req)
require.NoError(t, err)
require.False(t, res.IsError, "safe_delete errored: %s", toolResultText(res))
var payload map[string]any
require.NoError(t, json.Unmarshal([]byte(res.Content[0].(mcplib.TextContent).Text), &payload))
return payload
}
// 1. Plan (dry-run): one removable caller patch.
plan := callRes(map[string]any{"id": targetID, "propagate": true, "dry_run": true})
require.Equal(t, "propagation_plan", plan["status"])
require.Equal(t, float64(1), plan["removable"])
require.Equal(t, float64(0), plan["manual"])
// 2. Apply: patches the caller and deletes the target.
applied := callRes(map[string]any{"id": targetID, "propagate": true, "dry_run": false})
status, _ := applied["status"].(string)
require.Contains(t, []string{"deleted", "deleted_by_propagation"}, status)
// The caller's standalone Target() call was removed.
callerSrc, err := os.ReadFile(filepath.Join(dir, "caller.go"))
require.NoError(t, err)
require.NotContains(t, string(callerSrc), "Target()", "the call site should be removed")
}