github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/edit/complete_getopt_test.go (about)

     1  package edit
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/markusbkk/elvish/pkg/eval"
     7  	. "github.com/markusbkk/elvish/pkg/eval/evaltest"
     8  	"github.com/markusbkk/elvish/pkg/parse"
     9  	"github.com/markusbkk/elvish/pkg/ui"
    10  )
    11  
    12  func setupCompleteGetopt(ev *eval.Evaler) {
    13  	ev.ExtendBuiltin(eval.BuildNs().AddGoFn("complete-getopt", completeGetopt))
    14  
    15  	code := `fn complete {|@args|
    16  	           var opt-specs = [ [&short=a &long=all &desc="Show all"]
    17  	                             [&short=n &long=name &desc="Set name"
    18  	                              &arg-required=$true &arg-desc='new-name'
    19  	                              &completer= {|_| put name1 name2 }] ]
    20  	           var arg-handlers = [ {|_| put first1 first2 }
    21  	                                {|_| put second1 second2 } ... ]
    22  	           complete-getopt $args $opt-specs $arg-handlers
    23  	         }`
    24  	ev.Eval(parse.Source{Name: "[test init]", Code: code}, eval.EvalCfg{})
    25  }
    26  
    27  func TestCompleteGetopt(t *testing.T) {
    28  	TestWithSetup(t, setupCompleteGetopt,
    29  		// Complete argument
    30  		That("complete ''").Puts("first1", "first2"),
    31  		That("complete '' >&-").Throws(eval.ErrNoValueOutput),
    32  
    33  		// Complete option
    34  		That("complete -").Puts(
    35  			complexItem{Stem: "-a", Display: ui.T("-a (Show all)")},
    36  			complexItem{Stem: "--all", Display: ui.T("--all (Show all)")},
    37  			complexItem{Stem: "-n", Display: ui.T("-n new-name (Set name)")},
    38  			complexItem{Stem: "--name", Display: ui.T("--name new-name (Set name)")}),
    39  		That("complete - >&-").Throws(eval.ErrNoValueOutput),
    40  
    41  		// Complete long option
    42  		That("complete --").Puts(
    43  			complexItem{Stem: "--all", Display: ui.T("--all (Show all)")},
    44  			complexItem{Stem: "--name", Display: ui.T("--name new-name (Set name)")}),
    45  		That("complete --a").Puts(
    46  			complexItem{Stem: "--all", Display: ui.T("--all (Show all)")}),
    47  		That("complete -- >&-").Throws(eval.ErrNoValueOutput),
    48  
    49  		// Complete argument of short option
    50  		That("complete -n ''").Puts("name1", "name2"),
    51  		That("complete -n '' >&-").Throws(eval.ErrNoValueOutput),
    52  
    53  		// Complete argument of long option
    54  		That("complete --name ''").Puts("name1", "name2"),
    55  		That("complete --name '' >&-").Throws(eval.ErrNoValueOutput),
    56  
    57  		// Complete (normal) argument after option that doesn't take an argument
    58  		That("complete -a ''").Puts("first1", "first2"),
    59  		That("complete -a '' >&-").Throws(eval.ErrNoValueOutput),
    60  
    61  		// Complete second argument
    62  		That("complete arg1 ''").Puts("second1", "second2"),
    63  		That("complete arg1 '' >&-").Throws(eval.ErrNoValueOutput),
    64  
    65  		// Complete variadic argument
    66  		That("complete arg1 arg2 ''").Puts("second1", "second2"),
    67  		That("complete arg1 arg2 '' >&-").Throws(eval.ErrNoValueOutput),
    68  	)
    69  }
    70  
    71  func TestCompleteGetopt_TypeCheck(t *testing.T) {
    72  	TestWithSetup(t, setupCompleteGetopt,
    73  		That("complete-getopt [foo []] [] []").
    74  			Throws(ErrorWithMessage("arg should be string, got list")),
    75  
    76  		That("complete-getopt [] [foo] []").
    77  			Throws(ErrorWithMessage("opt should be map, got string")),
    78  		That("complete-getopt [] [[&short=[]]] []").
    79  			Throws(ErrorWithMessage("short should be string, got list")),
    80  		That("complete-getopt [] [[&short=foo]] []").
    81  			Throws(ErrorWithMessage("short should be exactly one rune, got foo")),
    82  		That("complete-getopt [] [[&long=[]]] []").
    83  			Throws(ErrorWithMessage("long should be string, got list")),
    84  		That("complete-getopt [] [[&]] []").
    85  			Throws(ErrorWithMessage("opt should have at least one of short and long forms")),
    86  		That("complete-getopt [] [[&short=a &arg-required=foo]] []").
    87  			Throws(ErrorWithMessage("arg-required should be bool, got string")),
    88  		That("complete-getopt [] [[&short=a &arg-optional=foo]] []").
    89  			Throws(ErrorWithMessage("arg-optional should be bool, got string")),
    90  		That("complete-getopt [] [[&short=a &arg-required=$true &arg-optional=$true]] []").
    91  			Throws(ErrorWithMessage("opt cannot have both arg-required and arg-optional")),
    92  		That("complete-getopt [] [[&short=a &desc=[]]] []").
    93  			Throws(ErrorWithMessage("desc should be string, got list")),
    94  		That("complete-getopt [] [[&short=a &arg-desc=[]]] []").
    95  			Throws(ErrorWithMessage("arg-desc should be string, got list")),
    96  		That("complete-getopt [] [[&short=a &completer=[]]] []").
    97  			Throws(ErrorWithMessage("completer should be fn, got list")),
    98  
    99  		That("complete-getopt [] [] [foo]").
   100  			Throws(ErrorWithMessage("string except for ... not allowed as argument handler, got foo")),
   101  		That("complete-getopt [] [] [[]]").
   102  			Throws(ErrorWithMessage("argument handler should be fn, got list")),
   103  	)
   104  }