Skip to main content
Glama
workspace_tool_test.go14 kB
package unit import ( "context" "encoding/json" "fmt" "os" "path/filepath" "testing" "github.com/MrFixit96/go-dev-mcp/internal/tools" "github.com/mark3labs/mcp-go/mcp" ) func TestExecuteGoWorkspaceTool(t *testing.T) { tempDir := t.TempDir() tests := []struct { name string command string workspacePath string expectedError bool setupFunc func(string) error cleanupFunc func(string) error }{ { name: "missing command parameter", command: "", workspacePath: filepath.Join(tempDir, "test-workspace"), expectedError: true, }, { name: "missing workspace_path parameter", command: "init", workspacePath: "", expectedError: true, }, { name: "unknown command", command: "unknown", workspacePath: filepath.Join(tempDir, "test-workspace"), expectedError: true, }, { name: "workspace init success", command: "init", workspacePath: filepath.Join(tempDir, "test-workspace-init"), expectedError: false, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, { name: "workspace use success", command: "use", workspacePath: filepath.Join(tempDir, "test-workspace-use"), expectedError: false, setupFunc: func(path string) error { // Create workspace first if err := os.MkdirAll(path, 0755); err != nil { return err } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": path, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) return err }, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, { name: "workspace sync success", command: "sync", workspacePath: filepath.Join(tempDir, "test-workspace-sync"), expectedError: false, setupFunc: func(path string) error { // Create workspace first if err := os.MkdirAll(path, 0755); err != nil { return err } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": path, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) return err }, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, { name: "workspace edit success", command: "edit", workspacePath: filepath.Join(tempDir, "test-workspace-edit"), expectedError: false, setupFunc: func(path string) error { // Create workspace first if err := os.MkdirAll(path, 0755); err != nil { return err } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": path, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) return err }, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, { name: "workspace vendor success", command: "vendor", workspacePath: filepath.Join(tempDir, "test-workspace-vendor"), expectedError: false, setupFunc: func(path string) error { // Create workspace first if err := os.MkdirAll(path, 0755); err != nil { return err } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": path, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) return err }, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, { name: "workspace info success", command: "info", workspacePath: filepath.Join(tempDir, "test-workspace-info"), expectedError: false, setupFunc: func(path string) error { // Create workspace first if err := os.MkdirAll(path, 0755); err != nil { return err } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": path, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) return err }, cleanupFunc: func(path string) error { return os.RemoveAll(path) }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Setup if tt.setupFunc != nil { if err := tt.setupFunc(tt.workspacePath); err != nil { t.Fatalf("Setup failed: %v", err) } } // Cleanup defer func() { if tt.cleanupFunc != nil { tt.cleanupFunc(tt.workspacePath) } }() // Create mock request reqArgs := map[string]interface{}{ "command": tt.command, "workspace_path": tt.workspacePath, } // Add modules parameter for 'use' command if tt.command == "use" { reqArgs["modules"] = []interface{}{"./test-module"} } req := createMockRequest(reqArgs) // Execute result, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) // Verify if err != nil { t.Fatalf("Unexpected error: %v", err) } if tt.expectedError { if !result.IsError { t.Errorf("Expected error but got success") } } else { if result.IsError { t.Errorf("Expected success but got error: %v", result.Content) } } }) } } func TestWorkspaceCommands(t *testing.T) { tempDir := t.TempDir() workspacePath := filepath.Join(tempDir, "test-workspace") t.Run("init command", func(t *testing.T) { req := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { t.Fatalf("Unexpected error: %v", err) } if result.IsError { textContent, ok := result.Content[0].(mcp.TextContent) if ok { t.Errorf("Init command failed: %v", textContent.Text) } else { t.Errorf("Init command failed: %v", result.Content) } } // Check if go.work file was created goWorkPath := filepath.Join(workspacePath, "go.work") if !fileExists(goWorkPath) { t.Errorf("go.work file was not created") } }) t.Run("info command", func(t *testing.T) { req := createMockRequest(map[string]interface{}{ "command": "info", "workspace_path": workspacePath, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { t.Fatalf("Unexpected error: %v", err) } if result.IsError { textContent, ok := result.Content[0].(mcp.TextContent) if ok { t.Errorf("Info command failed: %v", textContent.Text) } else { t.Errorf("Info command failed: %v", result.Content) } } // Verify response structure var response map[string]interface{} textContent, ok := result.Content[0].(mcp.TextContent) if !ok { t.Errorf("Expected TextContent, got %T", result.Content[0]) return } if err := json.Unmarshal([]byte(textContent.Text), &response); err != nil { t.Errorf("Failed to parse response JSON: %v", err) } if success, ok := response["success"].(bool); !ok || !success { t.Errorf("Expected success=true in response") } }) t.Run("sync command", func(t *testing.T) { req := createMockRequest(map[string]interface{}{ "command": "sync", "workspace_path": workspacePath, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { t.Fatalf("Unexpected error: %v", err) } // Sync might fail if no modules are present, but should not error if result.IsError { // This is expected if workspace has no modules textContent, ok := result.Content[0].(mcp.TextContent) if ok { t.Logf("Sync failed as expected (no modules): %v", textContent.Text) } else { t.Logf("Sync failed as expected (no modules): %v", result.Content) } } }) } func TestWorkspaceUseCommand(t *testing.T) { tempDir := t.TempDir() workspacePath := filepath.Join(tempDir, "test-workspace") modulePath := filepath.Join(tempDir, "test-module") // Create a simple module if err := os.MkdirAll(modulePath, 0755); err != nil { t.Fatalf("Failed to create module directory: %v", err) } // Create go.mod file goModContent := "module example.com/test-module\n\ngo 1.21\n" if err := os.WriteFile(filepath.Join(modulePath, "go.mod"), []byte(goModContent), 0644); err != nil { t.Fatalf("Failed to create go.mod: %v", err) } // Initialize workspace first initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) if err != nil { t.Fatalf("Failed to initialize workspace: %v", err) } // Test use command useReq := createMockRequest(map[string]interface{}{ "command": "use", "workspace_path": workspacePath, "modules": []interface{}{modulePath}, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), useReq) if err != nil { t.Fatalf("Unexpected error: %v", err) } if result.IsError { textContent, ok := result.Content[0].(mcp.TextContent) if ok { t.Errorf("Use command failed: %v", textContent.Text) } else { t.Errorf("Use command failed: %v", result.Content) } } } // TestWorkspaceAdvancedScenarios tests complex workspace operations func TestWorkspaceAdvancedScenarios(t *testing.T) { t.Run("workspace with multiple modules", func(t *testing.T) { tempDir := t.TempDir() workspacePath := filepath.Join(tempDir, "multi-module-workspace") // Create module directories module1Path := filepath.Join(tempDir, "module1") module2Path := filepath.Join(tempDir, "module2") for _, modulePath := range []string{module1Path, module2Path} { if err := os.MkdirAll(modulePath, 0755); err != nil { t.Fatalf("Failed to create module directory: %v", err) } // Create go.mod file goModContent := fmt.Sprintf("module example.com/%s\n\ngo 1.21\n", filepath.Base(modulePath)) if err := os.WriteFile(filepath.Join(modulePath, "go.mod"), []byte(goModContent), 0644); err != nil { t.Fatalf("Failed to create go.mod: %v", err) } } // Initialize workspace initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, "modules": []interface{}{module1Path, module2Path}, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) if err != nil { t.Fatalf("Failed to initialize multi-module workspace: %v", err) } if result.IsError { t.Errorf("Expected success for multi-module init") } // Verify go.work file exists goWorkPath := filepath.Join(workspacePath, "go.work") if !fileExists(goWorkPath) { t.Errorf("go.work file was not created") } }) t.Run("workspace error handling", func(t *testing.T) { // Test operations on non-existent workspace req := createMockRequest(map[string]interface{}{ "command": "sync", "workspace_path": "/non/existent/path", }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { t.Fatalf("Unexpected error: %v", err) } if !result.IsError { t.Errorf("Expected error for non-existent workspace") } }) t.Run("workspace use with invalid modules", func(t *testing.T) { tempDir := t.TempDir() workspacePath := filepath.Join(tempDir, "test-workspace") // Initialize workspace first initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) if err != nil { t.Fatalf("Failed to initialize workspace: %v", err) } // Try to use non-existent modules useReq := createMockRequest(map[string]interface{}{ "command": "use", "workspace_path": workspacePath, "modules": []interface{}{"/non/existent/module"}, }) result, err := tools.ExecuteGoWorkspaceTool(context.Background(), useReq) if err != nil { t.Fatalf("Unexpected error: %v", err) } // This might fail or succeed depending on Go's behavior // Just ensure we don't crash if result == nil { t.Errorf("Expected non-nil result") } }) } func createMockRequest(args map[string]interface{}) mcp.CallToolRequest { return mcp.CallToolRequest{ Params: struct { Name string `json:"name"` Arguments interface{} `json:"arguments,omitempty"` Meta *mcp.Meta `json:"_meta,omitempty"` }{ Name: "go_workspace", Arguments: args, }, } } // fileExists checks if a file exists and is not a directory func fileExists(filename string) bool { info, err := os.Stat(filename) if os.IsNotExist(err) { return false } return !info.IsDir() } // Benchmark tests for workspace operations func BenchmarkWorkspaceInit(b *testing.B) { for i := 0; i < b.N; i++ { tempDir := b.TempDir() workspacePath := filepath.Join(tempDir, "bench-workspace") req := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { b.Fatalf("Benchmark failed: %v", err) } } } func BenchmarkWorkspaceInfo(b *testing.B) { tempDir := b.TempDir() workspacePath := filepath.Join(tempDir, "bench-workspace") // Initialize workspace once initReq := createMockRequest(map[string]interface{}{ "command": "init", "workspace_path": workspacePath, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), initReq) if err != nil { b.Fatalf("Failed to initialize workspace: %v", err) } b.ResetTimer() for i := 0; i < b.N; i++ { req := createMockRequest(map[string]interface{}{ "command": "info", "workspace_path": workspacePath, }) _, err := tools.ExecuteGoWorkspaceTool(context.Background(), req) if err != nil { b.Fatalf("Benchmark failed: %v", err) } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MrFixit96/go-dev-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server