summaryrefslogtreecommitdiff
path: root/test/example_test.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-01-14 14:25:54 -0600
committerJeff Carr <[email protected]>2024-01-14 14:25:54 -0600
commit530fcb84d482355ce44af5371142c9f97e20672d (patch)
treef208647640f050bc8c47aad4746c70223270979f /test/example_test.go
parentbf629a16cbe505e81b6347813a918770a3b727df (diff)
isolate tests
Signed-off-by: Jeff Carr <[email protected]>
Diffstat (limited to 'test/example_test.go')
-rw-r--r--test/example_test.go540
1 files changed, 540 insertions, 0 deletions
diff --git a/test/example_test.go b/test/example_test.go
new file mode 100644
index 0000000..4bd7632
--- /dev/null
+++ b/test/example_test.go
@@ -0,0 +1,540 @@
+package arg
+
+import (
+ "fmt"
+ "net"
+ "net/mail"
+ "net/url"
+ "os"
+ "strings"
+ "time"
+)
+
+func split(s string) []string {
+ return strings.Split(s, " ")
+}
+
+// This example demonstrates basic usage
+func Example() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --foo=hello --bar")
+
+ var args struct {
+ Foo string
+ Bar bool
+ }
+ MustParse(&args)
+ fmt.Println(args.Foo, args.Bar)
+ // output: hello true
+}
+
+// This example demonstrates arguments that have default values
+func Example_defaultValues() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example")
+
+ var args struct {
+ Foo string `default:"abc"`
+ }
+ MustParse(&args)
+ fmt.Println(args.Foo)
+ // output: abc
+}
+
+// This example demonstrates arguments that are required
+func Example_requiredArguments() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --foo=abc --bar")
+
+ var args struct {
+ Foo string `arg:"required"`
+ Bar bool
+ }
+ MustParse(&args)
+ fmt.Println(args.Foo, args.Bar)
+ // output: abc true
+}
+
+// This example demonstrates positional arguments
+func Example_positionalArguments() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example in out1 out2 out3")
+
+ var args struct {
+ Input string `arg:"positional"`
+ Output []string `arg:"positional"`
+ }
+ MustParse(&args)
+ fmt.Println("In:", args.Input)
+ fmt.Println("Out:", args.Output)
+ // output:
+ // In: in
+ // Out: [out1 out2 out3]
+}
+
+// This example demonstrates arguments that have multiple values
+func Example_multipleValues() {
+ // The args you would pass in on the command line
+ os.Args = split("./example --database localhost --ids 1 2 3")
+
+ var args struct {
+ Database string
+ IDs []int64
+ }
+ MustParse(&args)
+ fmt.Printf("Fetching the following IDs from %s: %v", args.Database, args.IDs)
+ // output: Fetching the following IDs from localhost: [1 2 3]
+}
+
+// This example demonstrates arguments with keys and values
+func Example_mappings() {
+ // The args you would pass in on the command line
+ os.Args = split("./example --userids john=123 mary=456")
+
+ var args struct {
+ UserIDs map[string]int
+ }
+ MustParse(&args)
+ fmt.Println(args.UserIDs)
+ // output: map[john:123 mary:456]
+}
+
+type commaSeparated struct {
+ M map[string]string
+}
+
+func (c *commaSeparated) UnmarshalText(b []byte) error {
+ c.M = make(map[string]string)
+ for _, part := range strings.Split(string(b), ",") {
+ pos := strings.Index(part, "=")
+ if pos == -1 {
+ return fmt.Errorf("error parsing %q, expected format key=value", part)
+ }
+ c.M[part[:pos]] = part[pos+1:]
+ }
+ return nil
+}
+
+// This example demonstrates arguments with keys and values separated by commas
+func Example_mappingWithCommas() {
+ // The args you would pass in on the command line
+ os.Args = split("./example --values one=two,three=four")
+
+ var args struct {
+ Values commaSeparated
+ }
+ MustParse(&args)
+ fmt.Println(args.Values.M)
+ // output: map[one:two three:four]
+}
+
+// This eample demonstrates multiple value arguments that can be mixed with
+// other arguments.
+func Example_multipleMixed() {
+ os.Args = split("./example -c cmd1 db1 -f file1 db2 -c cmd2 -f file2 -f file3 db3 -c cmd3")
+ var args struct {
+ Commands []string `arg:"-c,separate"`
+ Files []string `arg:"-f,separate"`
+ Databases []string `arg:"positional"`
+ }
+ MustParse(&args)
+ fmt.Println("Commands:", args.Commands)
+ fmt.Println("Files:", args.Files)
+ fmt.Println("Databases:", args.Databases)
+
+ // output:
+ // Commands: [cmd1 cmd2 cmd3]
+ // Files: [file1 file2 file3]
+ // Databases: [db1 db2 db3]
+}
+
+// This example shows the usage string generated by go-arg
+func Example_helpText() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --help")
+
+ var args struct {
+ Input string `arg:"positional,required"`
+ Output []string `arg:"positional"`
+ Verbose bool `arg:"-v" help:"verbosity level"`
+ Dataset string `help:"dataset to use"`
+ Optimize int `arg:"-O,--optim" help:"optimization level"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+ // Usage: example [--verbose] [--dataset DATASET] [--optim OPTIM] INPUT [OUTPUT [OUTPUT ...]]
+ //
+ // Positional arguments:
+ // INPUT
+ // OUTPUT
+ //
+ // Options:
+ // --verbose, -v verbosity level
+ // --dataset DATASET dataset to use
+ // --optim OPTIM, -O OPTIM
+ // optimization level
+ // --help, -h display this help and exit
+}
+
+// This example shows the usage string generated by go-arg with customized placeholders
+func Example_helpPlaceholder() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --help")
+
+ var args struct {
+ Input string `arg:"positional,required" placeholder:"SRC"`
+ Output []string `arg:"positional" placeholder:"DST"`
+ Optimize int `arg:"-O" help:"optimization level" placeholder:"LEVEL"`
+ MaxJobs int `arg:"-j" help:"maximum number of simultaneous jobs" placeholder:"N"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+
+ // Usage: example [--optimize LEVEL] [--maxjobs N] SRC [DST [DST ...]]
+
+ // Positional arguments:
+ // SRC
+ // DST
+
+ // Options:
+ // --optimize LEVEL, -O LEVEL
+ // optimization level
+ // --maxjobs N, -j N maximum number of simultaneous jobs
+ // --help, -h display this help and exit
+}
+
+// This example shows the usage string generated by go-arg when using subcommands
+func Example_helpTextWithSubcommand() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --help")
+
+ type getCmd struct {
+ Item string `arg:"positional" help:"item to fetch"`
+ }
+
+ type listCmd struct {
+ Format string `help:"output format"`
+ Limit int
+ }
+
+ var args struct {
+ Verbose bool
+ Get *getCmd `arg:"subcommand" help:"fetch an item and print it"`
+ List *listCmd `arg:"subcommand" help:"list available items"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+ // Usage: example [--verbose] <command> [<args>]
+ //
+ // Options:
+ // --verbose
+ // --help, -h display this help and exit
+ //
+ // Commands:
+ // get fetch an item and print it
+ // list list available items
+}
+
+// This example shows the usage string generated by go-arg when using subcommands
+func Example_helpTextWhenUsingSubcommand() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example get --help")
+
+ type getCmd struct {
+ Item string `arg:"positional,required" help:"item to fetch"`
+ }
+
+ type listCmd struct {
+ Format string `help:"output format"`
+ Limit int
+ }
+
+ var args struct {
+ Verbose bool
+ Get *getCmd `arg:"subcommand" help:"fetch an item and print it"`
+ List *listCmd `arg:"subcommand" help:"list available items"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+ // Usage: example get ITEM
+ //
+ // Positional arguments:
+ // ITEM item to fetch
+ //
+ // Global options:
+ // --verbose
+ // --help, -h display this help and exit
+}
+
+// This example shows how to print help for an explicit subcommand
+func Example_writeHelpForSubcommand() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example get --help")
+
+ type getCmd struct {
+ Item string `arg:"positional" help:"item to fetch"`
+ }
+
+ type listCmd struct {
+ Format string `help:"output format"`
+ Limit int
+ }
+
+ var args struct {
+ Verbose bool
+ Get *getCmd `arg:"subcommand" help:"fetch an item and print it"`
+ List *listCmd `arg:"subcommand" help:"list available items"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ exit := func(int) {}
+
+ p, err := NewParser(Config{Exit: exit}, &args)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ err = p.WriteHelpForSubcommand(os.Stdout, "list")
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ // output:
+ // Usage: example list [--format FORMAT] [--limit LIMIT]
+ //
+ // Options:
+ // --format FORMAT output format
+ // --limit LIMIT
+ //
+ // Global options:
+ // --verbose
+ // --help, -h display this help and exit
+}
+
+// This example shows how to print help for a subcommand that is nested several levels deep
+func Example_writeHelpForSubcommandNested() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example get --help")
+
+ type mostNestedCmd struct {
+ Item string
+ }
+
+ type nestedCmd struct {
+ MostNested *mostNestedCmd `arg:"subcommand"`
+ }
+
+ type topLevelCmd struct {
+ Nested *nestedCmd `arg:"subcommand"`
+ }
+
+ var args struct {
+ TopLevel *topLevelCmd `arg:"subcommand"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ exit := func(int) {}
+
+ p, err := NewParser(Config{Exit: exit}, &args)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ err = p.WriteHelpForSubcommand(os.Stdout, "toplevel", "nested", "mostnested")
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ // output:
+ // Usage: example toplevel nested mostnested [--item ITEM]
+ //
+ // Options:
+ // --item ITEM
+ // --help, -h display this help and exit
+}
+
+// This example shows the error string generated by go-arg when an invalid option is provided
+func Example_errorText() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example --optimize INVALID")
+
+ var args struct {
+ Input string `arg:"positional,required"`
+ Output []string `arg:"positional"`
+ Verbose bool `arg:"-v" help:"verbosity level"`
+ Dataset string `help:"dataset to use"`
+ Optimize int `arg:"-O,help:optimization level"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+ // Usage: example [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] INPUT [OUTPUT [OUTPUT ...]]
+ // error: error processing --optimize: strconv.ParseInt: parsing "INVALID": invalid syntax
+}
+
+// This example shows the error string generated by go-arg when an invalid option is provided
+func Example_errorTextForSubcommand() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example get --count INVALID")
+
+ type getCmd struct {
+ Count int
+ }
+
+ var args struct {
+ Get *getCmd `arg:"subcommand"`
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ // output:
+ // Usage: example get [--count COUNT]
+ // error: error processing --count: strconv.ParseInt: parsing "INVALID": invalid syntax
+}
+
+// This example demonstrates use of subcommands
+func Example_subcommand() {
+ // These are the args you would pass in on the command line
+ os.Args = split("./example commit -a -m what-this-commit-is-about")
+
+ type CheckoutCmd struct {
+ Branch string `arg:"positional"`
+ Track bool `arg:"-t"`
+ }
+ type CommitCmd struct {
+ All bool `arg:"-a"`
+ Message string `arg:"-m"`
+ }
+ type PushCmd struct {
+ Remote string `arg:"positional"`
+ Branch string `arg:"positional"`
+ SetUpstream bool `arg:"-u"`
+ }
+ var args struct {
+ Checkout *CheckoutCmd `arg:"subcommand:checkout"`
+ Commit *CommitCmd `arg:"subcommand:commit"`
+ Push *PushCmd `arg:"subcommand:push"`
+ Quiet bool `arg:"-q"` // this flag is global to all subcommands
+ }
+
+ // This is only necessary when running inside golang's runnable example harness
+ mustParseExit = func(int) {}
+
+ MustParse(&args)
+
+ switch {
+ case args.Checkout != nil:
+ fmt.Printf("checkout requested for branch %s\n", args.Checkout.Branch)
+ case args.Commit != nil:
+ fmt.Printf("commit requested with message \"%s\"\n", args.Commit.Message)
+ case args.Push != nil:
+ fmt.Printf("push requested from %s to %s\n", args.Push.Branch, args.Push.Remote)
+ }
+
+ // output:
+ // commit requested with message "what-this-commit-is-about"
+}
+
+func Example_allSupportedTypes() {
+ // These are the args you would pass in on the command line
+ os.Args = []string{}
+
+ var args struct {
+ Bool bool
+ Byte byte
+ Rune rune
+ Int int
+ Int8 int8
+ Int16 int16
+ Int32 int32
+ Int64 int64
+ Float32 float32
+ Float64 float64
+ String string
+ Duration time.Duration
+ URL url.URL
+ Email mail.Address
+ MAC net.HardwareAddr
+ }
+
+ // go-arg supports each of the types above, as well as pointers to any of
+ // the above and slices of any of the above. It also supports any types that
+ // implements encoding.TextUnmarshaler.
+
+ MustParse(&args)
+
+ // output:
+}
+
+func Example_envVarOnly() {
+ os.Args = split("./example")
+ _ = os.Setenv("AUTH_KEY", "my_key")
+
+ defer os.Unsetenv("AUTH_KEY")
+
+ var args struct {
+ AuthKey string `arg:"--,env:AUTH_KEY"`
+ }
+
+ MustParse(&args)
+
+ fmt.Println(args.AuthKey)
+ // output: my_key
+}
+
+func Example_envVarOnlyShouldIgnoreFlag() {
+ os.Args = split("./example --=my_key")
+
+ var args struct {
+ AuthKey string `arg:"--,env:AUTH_KEY"`
+ }
+
+ err := Parse(&args)
+
+ fmt.Println(err)
+ // output: unknown argument --=my_key
+}
+
+func Example_envVarOnlyShouldIgnoreShortFlag() {
+ os.Args = split("./example -=my_key")
+
+ var args struct {
+ AuthKey string `arg:"--,env:AUTH_KEY"`
+ }
+
+ err := Parse(&args)
+
+ fmt.Println(err)
+ // output: unknown argument -=my_key
+}