@@ -2691,3 +2691,189 @@ func TestFixedCompletions(t *testing.T) {
2691
2691
t .Errorf ("expected: %q, got: %q" , expected , output )
2692
2692
}
2693
2693
}
2694
+
2695
+ func TestCompletionForGroupedFlags (t * testing.T ) {
2696
+ getCmd := func () * Command {
2697
+ rootCmd := & Command {
2698
+ Use : "root" ,
2699
+ Run : emptyRun ,
2700
+ }
2701
+ childCmd := & Command {
2702
+ Use : "child" ,
2703
+ ValidArgsFunction : func (cmd * Command , args []string , toComplete string ) ([]string , ShellCompDirective ) {
2704
+ return []string {"subArg" }, ShellCompDirectiveNoFileComp
2705
+ },
2706
+ Run : emptyRun ,
2707
+ }
2708
+ rootCmd .AddCommand (childCmd )
2709
+
2710
+ rootCmd .PersistentFlags ().Int ("ingroup1" , - 1 , "ingroup1" )
2711
+ rootCmd .PersistentFlags ().String ("ingroup2" , "" , "ingroup2" )
2712
+
2713
+ childCmd .Flags ().Bool ("ingroup3" , false , "ingroup3" )
2714
+ childCmd .Flags ().Bool ("nogroup" , false , "nogroup" )
2715
+
2716
+ // Add flags to a group
2717
+ childCmd .MarkFlagsRequiredTogether ("ingroup1" , "ingroup2" , "ingroup3" )
2718
+
2719
+ return rootCmd
2720
+ }
2721
+
2722
+ // Each test case uses a unique command from the function above.
2723
+ testcases := []struct {
2724
+ desc string
2725
+ args []string
2726
+ expectedOutput string
2727
+ }{
2728
+ {
2729
+ desc : "flags in group not suggested without - prefix" ,
2730
+ args : []string {"child" , "" },
2731
+ expectedOutput : strings .Join ([]string {
2732
+ "subArg" ,
2733
+ ":4" ,
2734
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2735
+ },
2736
+ {
2737
+ desc : "flags in group suggested with - prefix" ,
2738
+ args : []string {"child" , "-" },
2739
+ expectedOutput : strings .Join ([]string {
2740
+ "--ingroup1" ,
2741
+ "--ingroup2" ,
2742
+ "--ingroup3" ,
2743
+ "--nogroup" ,
2744
+ ":4" ,
2745
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2746
+ },
2747
+ {
2748
+ desc : "when flag in group present, other flags in group suggested even without - prefix" ,
2749
+ args : []string {"child" , "--ingroup2" , "value" , "" },
2750
+ expectedOutput : strings .Join ([]string {
2751
+ "--ingroup1" ,
2752
+ "--ingroup3" ,
2753
+ "subArg" ,
2754
+ ":4" ,
2755
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2756
+ },
2757
+ {
2758
+ desc : "when all flags in group present, flags not suggested without - prefix" ,
2759
+ args : []string {"child" , "--ingroup1" , "8" , "--ingroup2" , "value2" , "--ingroup3" , "" },
2760
+ expectedOutput : strings .Join ([]string {
2761
+ "subArg" ,
2762
+ ":4" ,
2763
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2764
+ },
2765
+ {
2766
+ desc : "group ignored if some flags not applicable" ,
2767
+ args : []string {"--ingroup2" , "value" , "" },
2768
+ expectedOutput : strings .Join ([]string {
2769
+ "child" ,
2770
+ "completion" ,
2771
+ "help" ,
2772
+ ":4" ,
2773
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2774
+ },
2775
+ }
2776
+
2777
+ for _ , tc := range testcases {
2778
+ t .Run (tc .desc , func (t * testing.T ) {
2779
+ c := getCmd ()
2780
+ args := []string {ShellCompNoDescRequestCmd }
2781
+ args = append (args , tc .args ... )
2782
+ output , err := executeCommand (c , args ... )
2783
+ switch {
2784
+ case err == nil && output != tc .expectedOutput :
2785
+ t .Errorf ("expected: %q, got: %q" , tc .expectedOutput , output )
2786
+ case err != nil :
2787
+ t .Errorf ("Unexpected error %q" , err )
2788
+ }
2789
+ })
2790
+ }
2791
+ }
2792
+
2793
+ func TestCompletionForMutuallyExclusiveFlags (t * testing.T ) {
2794
+ getCmd := func () * Command {
2795
+ rootCmd := & Command {
2796
+ Use : "root" ,
2797
+ Run : emptyRun ,
2798
+ }
2799
+ childCmd := & Command {
2800
+ Use : "child" ,
2801
+ ValidArgsFunction : func (cmd * Command , args []string , toComplete string ) ([]string , ShellCompDirective ) {
2802
+ return []string {"subArg" }, ShellCompDirectiveNoFileComp
2803
+ },
2804
+ Run : emptyRun ,
2805
+ }
2806
+ rootCmd .AddCommand (childCmd )
2807
+
2808
+ rootCmd .PersistentFlags ().IntSlice ("ingroup1" , []int {1 }, "ingroup1" )
2809
+ rootCmd .PersistentFlags ().String ("ingroup2" , "" , "ingroup2" )
2810
+
2811
+ childCmd .Flags ().Bool ("ingroup3" , false , "ingroup3" )
2812
+ childCmd .Flags ().Bool ("nogroup" , false , "nogroup" )
2813
+
2814
+ // Add flags to a group
2815
+ childCmd .MarkFlagsMutuallyExclusive ("ingroup1" , "ingroup2" , "ingroup3" )
2816
+
2817
+ return rootCmd
2818
+ }
2819
+
2820
+ // Each test case uses a unique command from the function above.
2821
+ testcases := []struct {
2822
+ desc string
2823
+ args []string
2824
+ expectedOutput string
2825
+ }{
2826
+ {
2827
+ desc : "flags in mutually exclusive group not suggested without the - prefix" ,
2828
+ args : []string {"child" , "" },
2829
+ expectedOutput : strings .Join ([]string {
2830
+ "subArg" ,
2831
+ ":4" ,
2832
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2833
+ },
2834
+ {
2835
+ desc : "flags in mutually exclusive group suggested with the - prefix" ,
2836
+ args : []string {"child" , "-" },
2837
+ expectedOutput : strings .Join ([]string {
2838
+ "--ingroup1" ,
2839
+ "--ingroup2" ,
2840
+ "--ingroup3" ,
2841
+ "--nogroup" ,
2842
+ ":4" ,
2843
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2844
+ },
2845
+ {
2846
+ desc : "when flag in mutually exclusive group present, other flags in group not suggested even with the - prefix" ,
2847
+ args : []string {"child" , "--ingroup1" , "8" , "-" },
2848
+ expectedOutput : strings .Join ([]string {
2849
+ "--ingroup1" , // Should be suggested again since it is a slice
2850
+ "--nogroup" ,
2851
+ ":4" ,
2852
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2853
+ },
2854
+ {
2855
+ desc : "group ignored if some flags not applicable" ,
2856
+ args : []string {"--ingroup1" , "8" , "-" },
2857
+ expectedOutput : strings .Join ([]string {
2858
+ "--ingroup1" ,
2859
+ "--ingroup2" ,
2860
+ ":4" ,
2861
+ "Completion ended with directive: ShellCompDirectiveNoFileComp" , "" }, "\n " ),
2862
+ },
2863
+ }
2864
+
2865
+ for _ , tc := range testcases {
2866
+ t .Run (tc .desc , func (t * testing.T ) {
2867
+ c := getCmd ()
2868
+ args := []string {ShellCompNoDescRequestCmd }
2869
+ args = append (args , tc .args ... )
2870
+ output , err := executeCommand (c , args ... )
2871
+ switch {
2872
+ case err == nil && output != tc .expectedOutput :
2873
+ t .Errorf ("expected: %q, got: %q" , tc .expectedOutput , output )
2874
+ case err != nil :
2875
+ t .Errorf ("Unexpected error %q" , err )
2876
+ }
2877
+ })
2878
+ }
2879
+ }
0 commit comments