@@ -3,8 +3,23 @@ package toolsets
33import (
44 "errors"
55 "testing"
6+
7+ "github.com/modelcontextprotocol/go-sdk/mcp"
68)
79
10+ // mockTool creates a minimal ServerTool for testing
11+ func mockTool (name string , readOnly bool ) ServerTool {
12+ return ServerTool {
13+ Tool : mcp.Tool {
14+ Name : name ,
15+ Annotations : & mcp.ToolAnnotations {
16+ ReadOnlyHint : readOnly ,
17+ },
18+ },
19+ RegisterFunc : func (_ * mcp.Server ) {},
20+ }
21+ }
22+
823func TestNewToolsetGroupIsEmptyWithoutEverythingOn (t * testing.T ) {
924 tsg := NewToolsetGroup (false )
1025 if len (tsg .Toolsets ) != 0 {
@@ -262,3 +277,140 @@ func TestToolsetGroup_GetToolset(t *testing.T) {
262277 t .Errorf ("expected error to be ToolsetDoesNotExistError, got %v" , err )
263278 }
264279}
280+
281+ func TestAddDeprecatedToolAliases (t * testing.T ) {
282+ tsg := NewToolsetGroup (false )
283+
284+ // Test adding aliases
285+ tsg .AddDeprecatedToolAliases (map [string ]string {
286+ "old_name" : "new_name" ,
287+ "get_issue" : "issue_read" ,
288+ "create_pr" : "pull_request_create" ,
289+ })
290+
291+ if len (tsg .deprecatedAliases ) != 3 {
292+ t .Errorf ("expected 3 aliases, got %d" , len (tsg .deprecatedAliases ))
293+ }
294+ if tsg .deprecatedAliases ["old_name" ] != "new_name" {
295+ t .Errorf ("expected alias 'old_name' -> 'new_name', got '%s'" , tsg .deprecatedAliases ["old_name" ])
296+ }
297+ if tsg .deprecatedAliases ["get_issue" ] != "issue_read" {
298+ t .Errorf ("expected alias 'get_issue' -> 'issue_read'" )
299+ }
300+ if tsg .deprecatedAliases ["create_pr" ] != "pull_request_create" {
301+ t .Errorf ("expected alias 'create_pr' -> 'pull_request_create'" )
302+ }
303+ }
304+
305+ func TestIsDeprecatedToolAlias (t * testing.T ) {
306+ tsg := NewToolsetGroup (false )
307+ tsg .AddDeprecatedToolAliases (map [string ]string {"old_tool" : "new_tool" })
308+
309+ // Test with a deprecated alias
310+ canonical , isAlias := tsg .IsDeprecatedToolAlias ("old_tool" )
311+ if ! isAlias {
312+ t .Error ("expected 'old_tool' to be recognized as an alias" )
313+ }
314+ if canonical != "new_tool" {
315+ t .Errorf ("expected canonical name 'new_tool', got '%s'" , canonical )
316+ }
317+
318+ // Test with a non-alias
319+ canonical , isAlias = tsg .IsDeprecatedToolAlias ("some_other_tool" )
320+ if isAlias {
321+ t .Error ("expected 'some_other_tool' to not be an alias" )
322+ }
323+ if canonical != "" {
324+ t .Errorf ("expected empty canonical name, got '%s'" , canonical )
325+ }
326+ }
327+
328+ func TestFindToolByName_WithAlias (t * testing.T ) {
329+ tsg := NewToolsetGroup (false )
330+
331+ // Create a toolset with a tool
332+ toolset := NewToolset ("test-toolset" , "Test toolset" )
333+ toolset .readTools = append (toolset .readTools , mockTool ("issue_read" , true ))
334+ tsg .AddToolset (toolset )
335+
336+ // Add an alias
337+ tsg .AddDeprecatedToolAliases (map [string ]string {"get_issue" : "issue_read" })
338+
339+ // Find by canonical name
340+ tool , toolsetName , err := tsg .FindToolByName ("issue_read" )
341+ if err != nil {
342+ t .Fatalf ("expected no error, got %v" , err )
343+ }
344+ if tool .Tool .Name != "issue_read" {
345+ t .Errorf ("expected tool name 'issue_read', got '%s'" , tool .Tool .Name )
346+ }
347+ if toolsetName != "test-toolset" {
348+ t .Errorf ("expected toolset name 'test-toolset', got '%s'" , toolsetName )
349+ }
350+
351+ // Find by deprecated alias (should resolve to canonical)
352+ tool , toolsetName , err = tsg .FindToolByName ("get_issue" )
353+ if err != nil {
354+ t .Fatalf ("expected no error when using alias, got %v" , err )
355+ }
356+ if tool .Tool .Name != "issue_read" {
357+ t .Errorf ("expected tool name 'issue_read' when using alias, got '%s'" , tool .Tool .Name )
358+ }
359+ if toolsetName != "test-toolset" {
360+ t .Errorf ("expected toolset name 'test-toolset', got '%s'" , toolsetName )
361+ }
362+ }
363+
364+ func TestFindToolByName_NotFound (t * testing.T ) {
365+ tsg := NewToolsetGroup (false )
366+
367+ // Create a toolset with a tool
368+ toolset := NewToolset ("test-toolset" , "Test toolset" )
369+ toolset .readTools = append (toolset .readTools , mockTool ("some_tool" , true ))
370+ tsg .AddToolset (toolset )
371+
372+ // Try to find a non-existent tool
373+ _ , _ , err := tsg .FindToolByName ("nonexistent_tool" )
374+ if err == nil {
375+ t .Error ("expected error for non-existent tool" )
376+ }
377+
378+ var toolErr * ToolDoesNotExistError
379+ if ! errors .As (err , & toolErr ) {
380+ t .Errorf ("expected ToolDoesNotExistError, got %T" , err )
381+ }
382+ }
383+
384+ func TestRegisterSpecificTools_WithAliases (t * testing.T ) {
385+ tsg := NewToolsetGroup (false )
386+
387+ // Create a toolset with both read and write tools
388+ toolset := NewToolset ("test-toolset" , "Test toolset" )
389+ toolset .readTools = append (toolset .readTools , mockTool ("issue_read" , true ))
390+ toolset .writeTools = append (toolset .writeTools , mockTool ("issue_write" , false ))
391+ tsg .AddToolset (toolset )
392+
393+ // Add aliases
394+ tsg .AddDeprecatedToolAliases (map [string ]string {
395+ "get_issue" : "issue_read" ,
396+ "create_issue" : "issue_write" ,
397+ })
398+
399+ // Test registering with aliases (should work)
400+ err := tsg .RegisterSpecificTools (nil , []string {"get_issue" }, false )
401+ if err != nil {
402+ t .Errorf ("expected no error registering aliased tool, got %v" , err )
403+ }
404+
405+ // Test registering write tool alias in read-only mode (should skip but not error)
406+ err = tsg .RegisterSpecificTools (nil , []string {"create_issue" }, true )
407+ if err != nil {
408+ t .Errorf ("expected no error when skipping write tool in read-only mode, got %v" , err )
409+ }
410+
411+ // Test registering non-existent tool (should error)
412+ err = tsg .RegisterSpecificTools (nil , []string {"nonexistent" }, false )
413+ if err == nil {
414+ t .Error ("expected error for non-existent tool" )
415+ }
416+ }
0 commit comments