From 8d8acb825215e3855c8db0f6e9d6dd46c1cbb1aa Mon Sep 17 00:00:00 2001 From: shanglei Date: Thu, 28 May 2026 10:57:39 +0800 Subject: [PATCH] test(shortcuts): cover TypedShortcut descriptors, drop unused Mount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- shortcuts/common/typed_shortcut.go | 6 -- shortcuts/common/typed_shortcut_test.go | 74 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/shortcuts/common/typed_shortcut.go b/shortcuts/common/typed_shortcut.go index 238f5fe0e..0b692fac7 100644 --- a/shortcuts/common/typed_shortcut.go +++ b/shortcuts/common/typed_shortcut.go @@ -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) diff --git a/shortcuts/common/typed_shortcut_test.go b/shortcuts/common/typed_shortcut_test.go index b9c9f3042..b8328b03e 100644 --- a/shortcuts/common/typed_shortcut_test.go +++ b/shortcuts/common/typed_shortcut_test.go @@ -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) + } +}