Implements the analyze_profile MCP tool with TDD: exports Analyze() for direct testing, wraps it in AnalyzeHandler() for MCP, and adds AnalyzeTool() for the schema definition. Adds mark3labs/mcp-go v0.52.0 dependency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
1.9 KiB
Go
61 lines
1.9 KiB
Go
package tools_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"forge.lclr.dev/AI/xdebug-mcp/internal/cachegrind"
|
|
"forge.lclr.dev/AI/xdebug-mcp/internal/tools"
|
|
)
|
|
|
|
func makeTestProfile() *cachegrind.Profile {
|
|
main := &cachegrind.Function{Name: "main", File: "index.php", Costs: []int64{3500, 1700}}
|
|
query := &cachegrind.Function{Name: "query", File: "index.php", Costs: []int64{2000, 900}}
|
|
connect := &cachegrind.Function{Name: "connect", File: "index.php", Costs: []int64{250, 100}}
|
|
|
|
call1 := &cachegrind.Call{Caller: main, Callee: query, Count: 1, Costs: []int64{1500, 700}}
|
|
call2 := &cachegrind.Call{Caller: query, Callee: connect, Count: 2, Costs: []int64{500, 200}}
|
|
|
|
main.Calls = []*cachegrind.Call{call1}
|
|
query.CalledBy = []*cachegrind.Call{call1}
|
|
query.Calls = []*cachegrind.Call{call2}
|
|
connect.CalledBy = []*cachegrind.Call{call2}
|
|
|
|
return &cachegrind.Profile{
|
|
Cmd: "index.php",
|
|
Events: []string{"Time_(10ns)", "Memory_(bytes)"},
|
|
Functions: []*cachegrind.Function{main, query, connect},
|
|
ByName: map[string][]*cachegrind.Function{
|
|
"main": {main},
|
|
"query": {query},
|
|
"connect": {connect},
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestAnalyze_TopN(t *testing.T) {
|
|
p := makeTestProfile()
|
|
result := tools.Analyze(p, 3)
|
|
|
|
assert.Contains(t, result, "index.php")
|
|
assert.Contains(t, result, "Functions: 3 total")
|
|
assert.Contains(t, result, "main")
|
|
assert.Contains(t, result, "query")
|
|
assert.Contains(t, result, "connect")
|
|
// main must appear before query (higher cost)
|
|
assert.Less(t, strings.Index(result, "main"), strings.Index(result, "query"))
|
|
}
|
|
|
|
func TestAnalyze_TopNLimited(t *testing.T) {
|
|
p := makeTestProfile()
|
|
result := tools.Analyze(p, 1)
|
|
|
|
assert.Contains(t, result, "main")
|
|
assert.NotContains(t, result, "query") // only top 1
|
|
}
|
|
|
|
// require is used to avoid unused import error if tests change
|
|
var _ = require.New
|