package cobra import ( "context" "fmt" "io" "testing" ) func BenchmarkPerformanceParse(b *testing.B) { wide := performanceFlatTree(128) wideArgs := []string{"wide127"} deep, deepArgs := performanceNestedTree(24) options := ParseOptions{Context: context.Background(), Out: io.Discard, Err: io.Discard} for _, benchmark := range []struct { name string root *Command args []string }{ {name: "shallow_wide", root: wide, args: wideArgs}, {name: "deep", root: deep, args: deepArgs}, } { b.Run(benchmark.name, func(b *testing.B) { result := Parse(benchmark.root, benchmark.args, options) if result.Failure != nil { b.Fatalf("fixture parse failed: %s", result.Failure.Message) } b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { result := Parse(benchmark.root, benchmark.args, options) if result.Failure != nil { b.Fatalf("parse failed: %s", result.Failure.Message) } } }) } } func BenchmarkPerformanceSessionParseAndHelp(b *testing.B) { root := performanceFlatTree(8) args := []string{"wide007"} session := Prepare(root, ParseOptions{Context: context.Background(), Out: io.Discard, Err: io.Discard}) result := session.Parse(args) if result.Failure != nil { b.Fatalf("fixture parse failed: %s", result.Failure.Message) } if help, failure := session.RenderHelp(result.Path); failure != nil || help == "" { b.Fatalf("fixture help failed: %q %v", help, failure) } b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { result := session.Parse(args) if result.Failure != nil { b.Fatalf("parse failed: %s", result.Failure.Message) } if help, failure := session.RenderHelp(result.Path); failure != nil || help == "" { b.Fatalf("help failed: %q %v", help, failure) } } } func performanceFlatTree(count int) *Command { root := &Command{Name: "app", Children: make([]*Command, count)} for index := range root.Children { root.Children[index] = &Command{Name: fmt.Sprintf("wide%03d", index), Runnable: true} } return root } func performanceNestedTree(depth int) (*Command, []string) { path := make([]string, depth) for index := range path { path[index] = fmt.Sprintf("level%02d", index) } current := &Command{Name: path[depth-1], Runnable: true} for index := depth - 2; index >= 0; index-- { current = &Command{Name: path[index], Children: []*Command{ current, {Name: fmt.Sprintf("sibling%02d", index), Runnable: true}, }} } return &Command{Name: "app", Children: []*Command{current}}, path }