test(shortcuts): cover TypedShortcut descriptors, drop unused Mount

After reverting the im pilot in ccf654d3 the TypedShortcut framework
has no production caller, so the CI deadcode check flagged five
methods as newly unreachable. Resolve without breaking the framework:

- Remove TypedShortcut.Mount — a convenience wrapper over
  MountWithContext with zero callers (production OR test); not part
  of any interface contract.
- Add focused unit tests for the four ShortcutDescriptor methods
  required by the Mountable contract — GetAuthTypes plus
  ScopesForIdentity / ConditionalScopesForIdentity /
  DeclaredScopesForIdentity, with table-driven coverage of the
  user / bot / fallback / dedupe branches.

Locally verified: go run golang.org/x/tools/cmd/deadcode@v0.31.0
-test ./... against HEAD vs origin/main yields an empty diff.
This commit is contained in:
shanglei
2026-05-28 10:57:39 +08:00
parent ccf654d3f0
commit 8d8acb8252
2 changed files with 74 additions and 6 deletions

View File

@@ -97,12 +97,6 @@ func (s TypedShortcut[T]) DeclaredScopesForIdentity(identity string) []string {
return out
}
// Mount registers the typed shortcut on a parent command. Delegates to
// MountWithContext using a background context.
func (s TypedShortcut[T]) Mount(parent *cobra.Command, f *cmdutil.Factory) {
s.MountWithContext(context.Background(), parent, f)
}
// MountWithContext is implemented in Task 16's adapter section.
func (s TypedShortcut[T]) MountWithContext(ctx context.Context, parent *cobra.Command, f *cmdutil.Factory) {
mountTyped[T](ctx, parent, f, s)

View File

@@ -5,6 +5,7 @@ package common
import (
"context"
"slices"
"testing"
"github.com/spf13/cobra"
@@ -86,3 +87,76 @@ func TestMountTyped_HelpFuncInstalled(t *testing.T) {
t.Fatal("expected typed help func installed on subcommand")
}
}
func TestTypedShortcut_GetAuthTypes(t *testing.T) {
ts := TypedShortcut[*stubArgs]{AuthTypes: []string{"user", "bot"}}
if got := ts.GetAuthTypes(); !slices.Equal(got, []string{"user", "bot"}) {
t.Errorf("GetAuthTypes=%v", got)
}
if got := (TypedShortcut[*stubArgs]{}).GetAuthTypes(); got != nil {
t.Errorf("empty GetAuthTypes=%v, want nil", got)
}
}
func TestTypedShortcut_ScopesForIdentity(t *testing.T) {
ts := TypedShortcut[*stubArgs]{
Scopes: []string{"base"},
UserScopes: []string{"u"},
BotScopes: []string{"b"},
}
cases := []struct {
identity string
want []string
}{
{"user", []string{"u"}},
{"bot", []string{"b"}},
{"other", []string{"base"}},
{"", []string{"base"}},
}
for _, c := range cases {
if got := ts.ScopesForIdentity(c.identity); !slices.Equal(got, c.want) {
t.Errorf("ScopesForIdentity(%q)=%v, want %v", c.identity, got, c.want)
}
}
// Falls back to Scopes when the identity-specific list is empty.
fallback := TypedShortcut[*stubArgs]{Scopes: []string{"base"}}
if got := fallback.ScopesForIdentity("user"); !slices.Equal(got, []string{"base"}) {
t.Errorf("fallback user=%v", got)
}
}
func TestTypedShortcut_ConditionalScopesForIdentity(t *testing.T) {
ts := TypedShortcut[*stubArgs]{
ConditionalScopes: []string{"cbase"},
ConditionalUserScopes: []string{"cu"},
ConditionalBotScopes: []string{"cb"},
}
cases := []struct {
identity string
want []string
}{
{"user", []string{"cu"}},
{"bot", []string{"cb"}},
{"other", []string{"cbase"}},
}
for _, c := range cases {
if got := ts.ConditionalScopesForIdentity(c.identity); !slices.Equal(got, c.want) {
t.Errorf("ConditionalScopesForIdentity(%q)=%v, want %v", c.identity, got, c.want)
}
}
}
func TestTypedShortcut_DeclaredScopesForIdentity(t *testing.T) {
// Merges base + conditional, dedupes overlap, drops empty strings.
ts := TypedShortcut[*stubArgs]{
UserScopes: []string{"a", "b", ""},
ConditionalUserScopes: []string{"b", "c"},
}
if got := ts.DeclaredScopesForIdentity("user"); !slices.Equal(got, []string{"a", "b", "c"}) {
t.Errorf("merge+dedupe got %v", got)
}
// Returns nil when nothing is declared on either side.
if got := (TypedShortcut[*stubArgs]{}).DeclaredScopesForIdentity("user"); got != nil {
t.Errorf("empty got %v, want nil", got)
}
}