Files

129 lines
4.3 KiB
Go

// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cmdutil
import (
"strings"
"testing"
"github.com/spf13/cobra"
)
func TestSuggestFlagFix_falseGlue_starttime1(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("start", "", "begin time")
_ = cmd.Flags().SetAnnotation("start", "x-cli-format", []string{"date-time"})
err := errUnknownFlag("starttime1")
fix := SuggestFlagFix(cmd, err)
if strings.Contains(fix.Suggestion, "Space required") {
t.Fatalf("should not treat as glued value, got %q", fix.Suggestion)
}
if fix.AutoFixFlag != "" {
t.Fatalf("AutoFixFlag = %q, want empty", fix.AutoFixFlag)
}
if !strings.Contains(fix.Suggestion, "--help") {
t.Fatalf("expected help fallback, got %q", fix.Suggestion)
}
}
func TestSuggestFlagFix_trueGlue_isoDateSuffix(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("start", "", "begin time")
_ = cmd.Flags().SetAnnotation("start", "x-cli-format", []string{"date-time"})
err := errUnknownFlag("start2026-02-07")
fix := SuggestFlagFix(cmd, err)
wantSub := "Space required between flag and value: --start 2026-02-07"
if fix.Suggestion != wantSub {
t.Fatalf("Suggestion = %q, want %q", fix.Suggestion, wantSub)
}
if fix.AutoFixFlag != "start" || fix.AutoFixValue != "2026-02-07" {
t.Fatalf("AutoFix = %q/%q, want start/2026-02-07", fix.AutoFixFlag, fix.AutoFixValue)
}
}
func TestSuggestFlagFix_boolGlueNeverAutoFixes(t *testing.T) {
cmd := &cobra.Command{Use: "delete"}
cmd.Flags().Bool("yes", false, "confirm destructive operation")
for _, test := range []struct {
body string
want string
}{
{body: "yesfalse", want: "--yes=false"},
{body: "yestrue", want: "--yes=true"},
{body: "yesno", want: "--yes=false"},
} {
fix := SuggestFlagFix(cmd, errUnknownFlag(test.body))
if fix.AutoFixFlag != "" || fix.AutoFixValue != "" {
t.Fatalf("SuggestFlagFix(%q) auto-fix = %q/%q, want none", test.body, fix.AutoFixFlag, fix.AutoFixValue)
}
if strings.Contains(fix.Suggestion, "Space required") || !strings.Contains(fix.Suggestion, test.want) {
t.Fatalf("SuggestFlagFix(%q) suggestion = %q, want safe inline %q", test.body, fix.Suggestion, test.want)
}
}
}
func TestSuggestFlagFix_levenshteinAddsUsage(t *testing.T) {
cmd := &cobra.Command{Use: "send"}
cmd.Flags().String("conversation-id", "", "Conversation id")
err := errUnknownFlag("conversaton-id")
fix := SuggestFlagFix(cmd, err)
if !strings.HasPrefix(fix.Suggestion, "Did you mean --conversation-id?") {
t.Fatalf("unexpected: %q", fix.Suggestion)
}
if !strings.Contains(fix.Suggestion, "Conversation id") {
t.Fatalf("expected usage in hint, got %q", fix.Suggestion)
}
}
func TestSuggestFlagFix_skipsHiddenAlias(t *testing.T) {
cmd := &cobra.Command{Use: "list"}
cmd.Flags().String("start", "", "begin time")
_ = cmd.Flags().SetAnnotation("start", "x-cli-format", []string{"date-time"})
cmd.Flags().String("start-time", "", "")
_ = cmd.Flags().MarkHidden("start-time")
fix := SuggestFlagFix(cmd, errUnknownFlag("starttime1"))
if strings.Contains(fix.Suggestion, "start-time") {
t.Fatalf("must not recommend hidden alias, got %q", fix.Suggestion)
}
if !strings.Contains(fix.Suggestion, "--help") {
t.Fatalf("expected help fallback, got %q", fix.Suggestion)
}
}
func TestVisibleFlagNames_skipsHiddenAndInternal(t *testing.T) {
cmd := &cobra.Command{Use: "x"}
cmd.Flags().String("alpha", "", "")
cmd.Flags().String("json", "", "")
cmd.Flags().String("beta", "", "")
_ = cmd.Flags().MarkHidden("beta")
names := VisibleFlagNames(cmd)
if len(names) != 1 || names[0] != "alpha" {
t.Fatalf("got %v, want [alpha]", names)
}
}
func errUnknownFlag(body string) error {
return &stubFlagErr{msg: "unknown flag: --" + body}
}
type stubFlagErr struct{ msg string }
func (e *stubFlagErr) Error() string { return e.msg }