github.com/abdfnx/gh-api@v0.0.0-20210414084727-f5432eec23b8/internal/docs/man_test.go (about) 1 package docs 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 "github.com/spf13/cobra" 14 ) 15 16 func translate(in string) string { 17 return strings.Replace(in, "-", "\\-", -1) 18 } 19 20 func TestGenManDoc(t *testing.T) { 21 header := &GenManHeader{ 22 Title: "Project", 23 Section: "2", 24 } 25 26 // We generate on a subcommand so we have both subcommands and parents 27 buf := new(bytes.Buffer) 28 if err := GenMan(echoCmd, header, buf); err != nil { 29 t.Fatal(err) 30 } 31 output := buf.String() 32 33 // Make sure parent has - in CommandPath() in SEE ALSO: 34 parentPath := echoCmd.Parent().CommandPath() 35 dashParentPath := strings.Replace(parentPath, " ", "-", -1) 36 expected := translate(dashParentPath) 37 expected = expected + "(" + header.Section + ")" 38 checkStringContains(t, output, expected) 39 40 checkStringContains(t, output, translate(echoCmd.Name())) 41 checkStringContains(t, output, translate(echoCmd.Name())) 42 checkStringContains(t, output, "boolone") 43 checkStringContains(t, output, "rootflag") 44 checkStringContains(t, output, translate(rootCmd.Name())) 45 checkStringContains(t, output, translate(echoSubCmd.Name())) 46 checkStringOmits(t, output, translate(deprecatedCmd.Name())) 47 } 48 49 func TestGenManNoHiddenParents(t *testing.T) { 50 header := &GenManHeader{ 51 Title: "Project", 52 Section: "2", 53 } 54 55 // We generate on a subcommand so we have both subcommands and parents 56 for _, name := range []string{"rootflag", "strtwo"} { 57 f := rootCmd.PersistentFlags().Lookup(name) 58 f.Hidden = true 59 defer func() { f.Hidden = false }() 60 } 61 buf := new(bytes.Buffer) 62 if err := GenMan(echoCmd, header, buf); err != nil { 63 t.Fatal(err) 64 } 65 output := buf.String() 66 67 // Make sure parent has - in CommandPath() in SEE ALSO: 68 parentPath := echoCmd.Parent().CommandPath() 69 dashParentPath := strings.Replace(parentPath, " ", "-", -1) 70 expected := translate(dashParentPath) 71 expected = expected + "(" + header.Section + ")" 72 checkStringContains(t, output, expected) 73 74 checkStringContains(t, output, translate(echoCmd.Name())) 75 checkStringContains(t, output, translate(echoCmd.Name())) 76 checkStringContains(t, output, "boolone") 77 checkStringOmits(t, output, "rootflag") 78 checkStringContains(t, output, translate(rootCmd.Name())) 79 checkStringContains(t, output, translate(echoSubCmd.Name())) 80 checkStringOmits(t, output, translate(deprecatedCmd.Name())) 81 checkStringOmits(t, output, "OPTIONS INHERITED FROM PARENT COMMANDS") 82 } 83 84 func TestGenManSeeAlso(t *testing.T) { 85 rootCmd := &cobra.Command{Use: "root", Run: emptyRun} 86 aCmd := &cobra.Command{Use: "aaa", Run: emptyRun, Hidden: true} // #229 87 bCmd := &cobra.Command{Use: "bbb", Run: emptyRun} 88 cCmd := &cobra.Command{Use: "ccc", Run: emptyRun} 89 rootCmd.AddCommand(aCmd, bCmd, cCmd) 90 91 buf := new(bytes.Buffer) 92 header := &GenManHeader{} 93 if err := GenMan(rootCmd, header, buf); err != nil { 94 t.Fatal(err) 95 } 96 scanner := bufio.NewScanner(buf) 97 98 if err := assertLineFound(scanner, ".SH SEE ALSO"); err != nil { 99 t.Fatalf("Couldn't find SEE ALSO section header: %v", err) 100 } 101 if err := assertNextLineEquals(scanner, ".PP"); err != nil { 102 t.Fatalf("First line after SEE ALSO wasn't break-indent: %v", err) 103 } 104 if err := assertNextLineEquals(scanner, `\fBroot\-bbb(1)\fP, \fBroot\-ccc(1)\fP`); err != nil { 105 t.Fatalf("Second line after SEE ALSO wasn't correct: %v", err) 106 } 107 } 108 109 func TestManPrintFlagsHidesShortDeprecated(t *testing.T) { 110 c := &cobra.Command{} 111 c.Flags().StringP("foo", "f", "default", "Foo flag") 112 _ = c.Flags().MarkShorthandDeprecated("foo", "don't use it no more") 113 114 buf := new(bytes.Buffer) 115 manPrintFlags(buf, c.Flags()) 116 117 got := buf.String() 118 expected := "**--foo**=\"default\"\n\tFoo flag\n\n" 119 if got != expected { 120 t.Errorf("Expected %v, got %v", expected, got) 121 } 122 } 123 124 func TestGenManTree(t *testing.T) { 125 c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"} 126 header := &GenManHeader{Section: "2"} 127 tmpdir, err := ioutil.TempDir("", "test-gen-man-tree") 128 if err != nil { 129 t.Fatalf("Failed to create tmpdir: %s", err.Error()) 130 } 131 defer os.RemoveAll(tmpdir) 132 133 if err := GenManTree(c, header, tmpdir); err != nil { 134 t.Fatalf("GenManTree failed: %s", err.Error()) 135 } 136 137 if _, err := os.Stat(filepath.Join(tmpdir, "do.2")); err != nil { 138 t.Fatalf("Expected file 'do.2' to exist") 139 } 140 141 if header.Title != "" { 142 t.Fatalf("Expected header.Title to be unmodified") 143 } 144 } 145 146 func assertLineFound(scanner *bufio.Scanner, expectedLine string) error { 147 for scanner.Scan() { 148 line := scanner.Text() 149 if line == expectedLine { 150 return nil 151 } 152 } 153 154 if err := scanner.Err(); err != nil { 155 return fmt.Errorf("scan failed: %s", err) 156 } 157 158 return fmt.Errorf("hit EOF before finding %v", expectedLine) 159 } 160 161 func assertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error { 162 if scanner.Scan() { 163 line := scanner.Text() 164 if line == expectedLine { 165 return nil 166 } 167 return fmt.Errorf("got %v, not %v", line, expectedLine) 168 } 169 170 if err := scanner.Err(); err != nil { 171 return fmt.Errorf("scan failed: %v", err) 172 } 173 174 return fmt.Errorf("hit EOF before finding %v", expectedLine) 175 } 176 177 func BenchmarkGenManToFile(b *testing.B) { 178 file, err := ioutil.TempFile("", "") 179 if err != nil { 180 b.Fatal(err) 181 } 182 defer os.Remove(file.Name()) 183 defer file.Close() 184 185 b.ResetTimer() 186 for i := 0; i < b.N; i++ { 187 if err := GenMan(rootCmd, nil, file); err != nil { 188 b.Fatal(err) 189 } 190 } 191 }