github.com/alecthomas/kong@v0.9.1-0.20240410131203-2ab5733f1179/tag_test.go (about)

     1  package kong_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/alecthomas/assert/v2"
     8  
     9  	"github.com/alecthomas/kong"
    10  )
    11  
    12  func TestDefaultValueForOptionalArg(t *testing.T) {
    13  	var cli struct {
    14  		Arg string `kong:"arg,optional,default='\"\\'👌\\'\"'"`
    15  	}
    16  	p := mustNew(t, &cli)
    17  	_, err := p.Parse(nil)
    18  	assert.NoError(t, err)
    19  	assert.Equal(t, "\"'👌'\"", cli.Arg)
    20  }
    21  
    22  func TestNoValueInTag(t *testing.T) {
    23  	var cli struct {
    24  		Empty1 string `kong:"default"`
    25  		Empty2 string `kong:"default="`
    26  	}
    27  	p := mustNew(t, &cli)
    28  	_, err := p.Parse(nil)
    29  	assert.NoError(t, err)
    30  	assert.Equal(t, "", cli.Empty1)
    31  	assert.Equal(t, "", cli.Empty2)
    32  }
    33  
    34  func TestCommaInQuotes(t *testing.T) {
    35  	var cli struct {
    36  		Numbers string `kong:"default='1,2'"`
    37  	}
    38  	p := mustNew(t, &cli)
    39  	_, err := p.Parse(nil)
    40  	assert.NoError(t, err)
    41  	assert.Equal(t, "1,2", cli.Numbers)
    42  }
    43  
    44  func TestBadString(t *testing.T) {
    45  	var cli struct {
    46  		Numbers string `kong:"default='yay'n"`
    47  	}
    48  	_, err := kong.New(&cli)
    49  	assert.Error(t, err)
    50  }
    51  
    52  func TestNoQuoteEnd(t *testing.T) {
    53  	var cli struct {
    54  		Numbers string `kong:"default='yay"`
    55  	}
    56  	_, err := kong.New(&cli)
    57  	assert.Error(t, err)
    58  }
    59  
    60  func TestEscapedQuote(t *testing.T) {
    61  	var cli struct {
    62  		DoYouKnow string `kong:"default='i don\\'t know'"`
    63  	}
    64  	p := mustNew(t, &cli)
    65  	_, err := p.Parse(nil)
    66  	assert.NoError(t, err)
    67  	assert.Equal(t, "i don't know", cli.DoYouKnow)
    68  }
    69  
    70  func TestEscapingInQuotedTags(t *testing.T) {
    71  	var cli struct {
    72  		Regex1 string `kong:"default='\\d+\n'"`
    73  		Regex2 string `default:"\\d+\n"`
    74  	}
    75  	p := mustNew(t, &cli)
    76  	_, err := p.Parse(nil)
    77  	assert.NoError(t, err)
    78  	assert.Equal(t, "\\d+\n", cli.Regex1)
    79  	assert.Equal(t, "\\d+\n", cli.Regex2)
    80  }
    81  
    82  func TestBareTags(t *testing.T) {
    83  	var cli struct {
    84  		Cmd struct {
    85  			Arg  string `arg`
    86  			Flag string `required default:"👌"`
    87  		} `cmd`
    88  	}
    89  
    90  	p := mustNew(t, &cli)
    91  	_, err := p.Parse([]string{"cmd", "arg", "--flag=hi"})
    92  	assert.NoError(t, err)
    93  	assert.Equal(t, "hi", cli.Cmd.Flag)
    94  	assert.Equal(t, "arg", cli.Cmd.Arg)
    95  }
    96  
    97  func TestBareTagsWithJsonTag(t *testing.T) {
    98  	var cli struct {
    99  		Cmd struct {
   100  			Arg  string `json:"-" optional arg`
   101  			Flag string `json:"best_flag" default:"\"'👌'\""`
   102  		} `cmd json:"CMD"`
   103  	}
   104  
   105  	p := mustNew(t, &cli)
   106  	_, err := p.Parse([]string{"cmd"})
   107  	assert.NoError(t, err)
   108  	assert.Equal(t, "\"'👌'\"", cli.Cmd.Flag)
   109  	assert.Equal(t, "", cli.Cmd.Arg)
   110  }
   111  
   112  func TestManySeps(t *testing.T) {
   113  	var cli struct {
   114  		Arg string `arg    optional    default:"hi"`
   115  	}
   116  
   117  	p := mustNew(t, &cli)
   118  	_, err := p.Parse([]string{})
   119  	assert.NoError(t, err)
   120  	assert.Equal(t, "hi", cli.Arg)
   121  }
   122  
   123  func TestTagSetOnEmbeddedStruct(t *testing.T) {
   124  	type Embedded struct {
   125  		Key string `help:"A key from ${where}."`
   126  	}
   127  	var cli struct {
   128  		Embedded `set:"where=somewhere"`
   129  	}
   130  	buf := &strings.Builder{}
   131  	p := mustNew(t, &cli, kong.Writers(buf, buf), kong.Exit(func(int) {}))
   132  	_, err := p.Parse([]string{"--help"})
   133  	assert.NoError(t, err)
   134  	assert.Contains(t, buf.String(), `A key from somewhere.`)
   135  }
   136  
   137  func TestTagSetOnCommand(t *testing.T) {
   138  	type Command struct {
   139  		Key string `help:"A key from ${where}."`
   140  	}
   141  	var cli struct {
   142  		Command Command `set:"where=somewhere" cmd:""`
   143  	}
   144  	buf := &strings.Builder{}
   145  	p := mustNew(t, &cli, kong.Writers(buf, buf), kong.Exit(func(int) {}))
   146  	_, err := p.Parse([]string{"command", "--help"})
   147  	assert.NoError(t, err)
   148  	assert.Contains(t, buf.String(), `A key from somewhere.`)
   149  }
   150  
   151  func TestTagSetOnFlag(t *testing.T) {
   152  	var cli struct {
   153  		Flag string `set:"where=somewhere" help:"A key from ${where}."`
   154  	}
   155  	buf := &strings.Builder{}
   156  	p := mustNew(t, &cli, kong.Writers(buf, buf), kong.Exit(func(int) {}))
   157  	_, err := p.Parse([]string{"--help"})
   158  	assert.NoError(t, err)
   159  	assert.Contains(t, buf.String(), `A key from somewhere.`)
   160  }
   161  
   162  func TestTagAliases(t *testing.T) {
   163  	type Command struct {
   164  		Arg string `arg help:"Some arg"`
   165  	}
   166  	var cli struct {
   167  		Cmd Command `cmd aliases:"alias1, alias2"`
   168  	}
   169  	p := mustNew(t, &cli)
   170  	_, err := p.Parse([]string{"alias1", "arg"})
   171  	assert.NoError(t, err)
   172  	assert.Equal(t, "arg", cli.Cmd.Arg)
   173  	_, err = p.Parse([]string{"alias2", "arg"})
   174  	assert.NoError(t, err)
   175  	assert.Equal(t, "arg", cli.Cmd.Arg)
   176  }
   177  
   178  func TestTagAliasesConflict(t *testing.T) {
   179  	type Command struct {
   180  		Arg string `arg help:"Some arg"`
   181  	}
   182  	var cli struct {
   183  		Cmd      Command `cmd hidden aliases:"other-cmd"`
   184  		OtherCmd Command `cmd`
   185  	}
   186  	p := mustNew(t, &cli)
   187  	_, err := p.Parse([]string{"other-cmd", "arg"})
   188  	assert.NoError(t, err)
   189  	assert.Equal(t, "arg", cli.OtherCmd.Arg)
   190  }
   191  
   192  func TestTagAliasesSub(t *testing.T) {
   193  	type SubCommand struct {
   194  		Arg string `arg help:"Some arg"`
   195  	}
   196  	type Command struct {
   197  		SubCmd SubCommand `cmd aliases:"other-sub-cmd"`
   198  	}
   199  	var cli struct {
   200  		Cmd Command `cmd hidden`
   201  	}
   202  	p := mustNew(t, &cli)
   203  	_, err := p.Parse([]string{"cmd", "other-sub-cmd", "arg"})
   204  	assert.NoError(t, err)
   205  	assert.Equal(t, "arg", cli.Cmd.SubCmd.Arg)
   206  }
   207  
   208  func TestInvalidRuneErrors(t *testing.T) {
   209  	cli := struct {
   210  		Flag bool `short:"invalid"`
   211  	}{}
   212  	_, err := kong.New(&cli)
   213  	assert.EqualError(t, err, "<anonymous struct>.Flag: invalid short flag name \"invalid\": invalid rune")
   214  }