man_docs_test.go 4.5 KB

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