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