Commands are now hidden from help and return ErrUnknownCommand when invoked if their hook is nil (and for version, if Version string is also empty). No explicit DisabledCommands needed for MCPs that don't use login/setup/config/etc. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
688 lines
17 KiB
Go
688 lines
17 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestRunRoutesSetupHook(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
var got Invocation
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Version: "v1.2.3",
|
|
Args: []string{"setup", "--profile", "prod"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
Setup: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != CommandSetup {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandSetup)
|
|
}
|
|
wantArgs := []string{"--profile", "prod"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
}
|
|
|
|
func TestRunRoutesLoginHook(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
var got Invocation
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Version: "v1.2.3",
|
|
Args: []string{"login", "--force"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
Login: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != CommandLogin {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandLogin)
|
|
}
|
|
wantArgs := []string{"--force"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
}
|
|
|
|
func TestRunReturnsUnknownCommand(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"boom"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
if !errors.Is(err, ErrUnknownCommand) {
|
|
t.Fatalf("Run error = %v, want ErrUnknownCommand", err)
|
|
}
|
|
}
|
|
|
|
func TestRunReturnsCommandNotConfigured(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"config"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigShow: noop},
|
|
})
|
|
if !errors.Is(err, ErrSubcommandRequired) {
|
|
t.Fatalf("Run error = %v, want ErrSubcommandRequired", err)
|
|
}
|
|
if !strings.Contains(err.Error(), "show, test, delete") {
|
|
t.Fatalf("Run error = %q, want mention of show, test, delete", err)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsVersionByDefault(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Version: "v1.2.3",
|
|
Args: []string{"version"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
if stdout.String() != "v1.2.3\n" {
|
|
t.Fatalf("stdout = %q, want %q", stdout.String(), "v1.2.3\n")
|
|
}
|
|
}
|
|
|
|
func TestRunVersionHookOverridesDefault(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"version"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
Version: func(_ context.Context, inv Invocation) error {
|
|
_, err := inv.Stdout.Write([]byte("custom-version\n"))
|
|
return err
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
if stdout.String() != "custom-version\n" {
|
|
t.Fatalf("stdout = %q, want %q", stdout.String(), "custom-version\n")
|
|
}
|
|
}
|
|
|
|
func TestRunVersionAutoHiddenWithoutHookOrVersionString(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"version"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
if !errors.Is(err, ErrUnknownCommand) {
|
|
t.Fatalf("Run error = %v, want ErrUnknownCommand", err)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsGlobalHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Description: "Binaire MCP de test.",
|
|
Version: "v1.2.3",
|
|
Args: []string{"help"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{Setup: noop, MCP: noop, ConfigShow: noop, Update: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
for _, snippet := range []string{
|
|
"Usage:",
|
|
"setup",
|
|
"mcp",
|
|
"config",
|
|
"update",
|
|
"version",
|
|
} {
|
|
if !strings.Contains(text, snippet) {
|
|
t.Fatalf("help output missing %q: %s", snippet, text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsGlobalHelpWhenNoArgs(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Description: "Binaire MCP de test.",
|
|
Version: "v1.2.3",
|
|
Args: []string{},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{Setup: noop, MCP: noop, ConfigShow: noop, Update: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
for _, snippet := range []string{
|
|
"Usage:",
|
|
"setup",
|
|
"mcp",
|
|
"config",
|
|
"update",
|
|
"version",
|
|
} {
|
|
if !strings.Contains(text, snippet) {
|
|
t.Fatalf("help output missing %q: %s", snippet, text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsCommandHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"help", "update"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{Update: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "my-mcp update [args]") {
|
|
t.Fatalf("command help output = %q", text)
|
|
}
|
|
if !strings.Contains(text, "auto-update") {
|
|
t.Fatalf("command help output missing update description: %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsLoginCommandHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"help", "login"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{Login: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "my-mcp login [args]") {
|
|
t.Fatalf("command help output = %q", text)
|
|
}
|
|
if !strings.Contains(strings.ToLower(text), "bitwarden") {
|
|
t.Fatalf("command help output missing bitwarden description: %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsConfigHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"help", "config"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigShow: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
for _, snippet := range []string{
|
|
"my-mcp config <subcommand>",
|
|
"show",
|
|
"test",
|
|
} {
|
|
if !strings.Contains(text, snippet) {
|
|
t.Fatalf("config help output missing %q: %q", snippet, text)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsConfigSubcommandHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"help", "config", "show"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigShow: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "my-mcp config show [args]") {
|
|
t.Fatalf("config subcommand help output = %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunRoutesConfigShowHook(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
var got Invocation
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"config", "show", "--profile", "prod"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
ConfigShow: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != "config show" {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, "config show")
|
|
}
|
|
wantArgs := []string{"--profile", "prod"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
}
|
|
|
|
func TestRunConfigShowReturnsCommandNotConfigured(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"config", "show"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigTest: noop},
|
|
})
|
|
if !errors.Is(err, ErrCommandNotConfigured) {
|
|
t.Fatalf("Run error = %v, want ErrCommandNotConfigured", err)
|
|
}
|
|
}
|
|
|
|
func TestRunConfigReturnsUnknownSubcommand(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"config", "sync"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigShow: noop},
|
|
})
|
|
if !errors.Is(err, ErrUnknownSubcommand) {
|
|
t.Fatalf("Run error = %v, want ErrUnknownSubcommand", err)
|
|
}
|
|
}
|
|
|
|
func TestRunRoutesAliasToConfigSubcommandHook(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
var got Invocation
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Aliases: map[string][]string{
|
|
"doctor": {CommandConfig, ConfigSubcommandTest},
|
|
},
|
|
Args: []string{"doctor", "--profile", "work"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
ConfigTest: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != "config test" {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, "config test")
|
|
}
|
|
wantArgs := []string{"--profile", "work"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsAliasHelpFromHelpCommand(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Aliases: map[string][]string{
|
|
"doctor": {CommandConfig, ConfigSubcommandTest},
|
|
},
|
|
Args: []string{"help", "doctor"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigTest: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "my-mcp config test [args]") {
|
|
t.Fatalf("command help output = %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsAliasHelpFromTrailingHelpFlag(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
noop := func(_ context.Context, _ Invocation) error { return nil }
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Aliases: map[string][]string{
|
|
"doctor": {CommandConfig, ConfigSubcommandTest},
|
|
},
|
|
Args: []string{"doctor", "--help"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{ConfigTest: noop},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "my-mcp config test [args]") {
|
|
t.Fatalf("command help output = %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsAliasesInGlobalHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Aliases: map[string][]string{
|
|
"doctor": {CommandConfig, ConfigSubcommandTest},
|
|
},
|
|
AliasDescriptions: map[string]string{
|
|
"doctor": "Diagnostiquer la configuration locale.",
|
|
},
|
|
Args: []string{"help"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "Alias:") {
|
|
t.Fatalf("global help output missing alias section: %q", text)
|
|
}
|
|
if !strings.Contains(text, `doctor Diagnostiquer la configuration locale. (alias de "config test").`) {
|
|
t.Fatalf("global help output missing doctor alias details: %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunRoutesDoctorAliasWhenEnabled(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
var got Invocation
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
EnableDoctorAlias: true,
|
|
Args: []string{"doctor", "--profile", "prod"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
ConfigTest: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != "config test" {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, "config test")
|
|
}
|
|
wantArgs := []string{"--profile", "prod"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
}
|
|
|
|
func TestRunPrintsDoctorAliasInGlobalHelpWhenEnabled(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
EnableDoctorAlias: true,
|
|
Args: []string{"help"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
text := stdout.String()
|
|
if !strings.Contains(text, "Alias:") {
|
|
t.Fatalf("global help output missing alias section: %q", text)
|
|
}
|
|
if !strings.Contains(text, `doctor Diagnostiquer la configuration locale. (alias de "config test").`) {
|
|
t.Fatalf("global help output missing default doctor alias details: %q", text)
|
|
}
|
|
}
|
|
|
|
func TestRunAcceptsGlobalDebugFlagAndRoutesCommand(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
var got Invocation
|
|
|
|
t.Setenv("MCP_FRAMEWORK_BITWARDEN_DEBUG", "")
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"--debug", "setup", "--profile", "prod"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
Setup: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != CommandSetup {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandSetup)
|
|
}
|
|
wantArgs := []string{"--profile", "prod"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
if os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG") != "1" {
|
|
t.Fatalf("MCP_FRAMEWORK_BITWARDEN_DEBUG = %q, want %q", os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG"), "1")
|
|
}
|
|
}
|
|
|
|
func TestRunAcceptsGlobalDebugFlagAfterCommand(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
var got Invocation
|
|
|
|
t.Setenv("MCP_FRAMEWORK_BITWARDEN_DEBUG", "")
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"setup", "--debug", "--profile", "prod"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
Hooks: Hooks{
|
|
Setup: func(_ context.Context, inv Invocation) error {
|
|
got = inv
|
|
return nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run error = %v", err)
|
|
}
|
|
|
|
if got.Command != CommandSetup {
|
|
t.Fatalf("invocation command = %q, want %q", got.Command, CommandSetup)
|
|
}
|
|
wantArgs := []string{"--profile", "prod"}
|
|
if !slices.Equal(got.Args, wantArgs) {
|
|
t.Fatalf("invocation args = %v, want %v", got.Args, wantArgs)
|
|
}
|
|
if os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG") != "1" {
|
|
t.Fatalf("MCP_FRAMEWORK_BITWARDEN_DEBUG = %q, want %q", os.Getenv("MCP_FRAMEWORK_BITWARDEN_DEBUG"), "1")
|
|
}
|
|
}
|
|
|
|
func TestDisabledCommandReturnsUnknown(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
var stderr bytes.Buffer
|
|
|
|
err := Run(context.Background(), Options{
|
|
BinaryName: "my-mcp",
|
|
Args: []string{"login"},
|
|
DisabledCommands: []string{"login"},
|
|
Stdout: &stdout,
|
|
Stderr: &stderr,
|
|
})
|
|
|
|
if !errors.Is(err, ErrUnknownCommand) {
|
|
t.Fatalf("err = %v, want ErrUnknownCommand", err)
|
|
}
|
|
}
|
|
|
|
func TestDisabledCommandHiddenFromHelp(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
|
|
err := printGlobalHelp(Options{
|
|
BinaryName: "my-mcp",
|
|
DisabledCommands: []string{"login", "setup"},
|
|
Stdout: &stdout,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("printGlobalHelp error = %v", err)
|
|
}
|
|
|
|
out := stdout.String()
|
|
if strings.Contains(out, "login") {
|
|
t.Fatalf("help should not contain disabled command %q, got:\n%s", "login", out)
|
|
}
|
|
if strings.Contains(out, "setup") {
|
|
t.Fatalf("help should not contain disabled command %q, got:\n%s", "setup", out)
|
|
}
|
|
if !strings.Contains(out, "mcp") {
|
|
t.Fatalf("help should contain enabled command %q, got:\n%s", "mcp", out)
|
|
}
|
|
}
|
|
|
|
func TestDisabledCommandHelpReturnsUnknown(t *testing.T) {
|
|
var stdout bytes.Buffer
|
|
|
|
err := printHelp(Options{
|
|
BinaryName: "my-mcp",
|
|
DisabledCommands: []string{"login"},
|
|
Stdout: &stdout,
|
|
}, "login")
|
|
|
|
if !errors.Is(err, ErrUnknownCommand) {
|
|
t.Fatalf("err = %v, want ErrUnknownCommand", err)
|
|
}
|
|
}
|