...

Source file src/github.com/spf13/cobra/doc/man_docs_test.go

Documentation: github.com/spf13/cobra/doc

     1  // Copyright 2013-2023 The Cobra Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package doc
    16  
    17  import (
    18  	"bufio"
    19  	"bytes"
    20  	"fmt"
    21  	"io/ioutil"
    22  	"os"
    23  	"path/filepath"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/spf13/cobra"
    28  )
    29  
    30  func assertNoErr(t *testing.T, e error) {
    31  	if e != nil {
    32  		t.Error(e)
    33  	}
    34  }
    35  
    36  func translate(in string) string {
    37  	return strings.ReplaceAll(in, "-", "\\-")
    38  }
    39  
    40  func TestGenManDoc(t *testing.T) {
    41  	header := &GenManHeader{
    42  		Title:   "Project",
    43  		Section: "2",
    44  	}
    45  
    46  	// We generate on a subcommand so we have both subcommands and parents
    47  	buf := new(bytes.Buffer)
    48  	if err := GenMan(echoCmd, header, buf); err != nil {
    49  		t.Fatal(err)
    50  	}
    51  	output := buf.String()
    52  
    53  	// Make sure parent has - in CommandPath() in SEE ALSO:
    54  	parentPath := echoCmd.Parent().CommandPath()
    55  	dashParentPath := strings.ReplaceAll(parentPath, " ", "-")
    56  	expected := translate(dashParentPath)
    57  	expected = expected + "(" + header.Section + ")"
    58  	checkStringContains(t, output, expected)
    59  
    60  	checkStringContains(t, output, translate(echoCmd.Name()))
    61  	checkStringContains(t, output, translate(echoCmd.Name()))
    62  	checkStringContains(t, output, "boolone")
    63  	checkStringContains(t, output, "rootflag")
    64  	checkStringContains(t, output, translate(rootCmd.Name()))
    65  	checkStringContains(t, output, translate(echoSubCmd.Name()))
    66  	checkStringOmits(t, output, translate(deprecatedCmd.Name()))
    67  	checkStringContains(t, output, translate("Auto generated"))
    68  }
    69  
    70  func TestGenManNoHiddenParents(t *testing.T) {
    71  	header := &GenManHeader{
    72  		Title:   "Project",
    73  		Section: "2",
    74  	}
    75  
    76  	// We generate on a subcommand so we have both subcommands and parents
    77  	for _, name := range []string{"rootflag", "strtwo"} {
    78  		f := rootCmd.PersistentFlags().Lookup(name)
    79  		f.Hidden = true
    80  		defer func() { f.Hidden = false }()
    81  	}
    82  	buf := new(bytes.Buffer)
    83  	if err := GenMan(echoCmd, header, buf); err != nil {
    84  		t.Fatal(err)
    85  	}
    86  	output := buf.String()
    87  
    88  	// Make sure parent has - in CommandPath() in SEE ALSO:
    89  	parentPath := echoCmd.Parent().CommandPath()
    90  	dashParentPath := strings.ReplaceAll(parentPath, " ", "-")
    91  	expected := translate(dashParentPath)
    92  	expected = expected + "(" + header.Section + ")"
    93  	checkStringContains(t, output, expected)
    94  
    95  	checkStringContains(t, output, translate(echoCmd.Name()))
    96  	checkStringContains(t, output, translate(echoCmd.Name()))
    97  	checkStringContains(t, output, "boolone")
    98  	checkStringOmits(t, output, "rootflag")
    99  	checkStringContains(t, output, translate(rootCmd.Name()))
   100  	checkStringContains(t, output, translate(echoSubCmd.Name()))
   101  	checkStringOmits(t, output, translate(deprecatedCmd.Name()))
   102  	checkStringContains(t, output, translate("Auto generated"))
   103  	checkStringOmits(t, output, "OPTIONS INHERITED FROM PARENT COMMANDS")
   104  }
   105  
   106  func TestGenManNoGenTag(t *testing.T) {
   107  	echoCmd.DisableAutoGenTag = true
   108  	defer func() { echoCmd.DisableAutoGenTag = false }()
   109  
   110  	header := &GenManHeader{
   111  		Title:   "Project",
   112  		Section: "2",
   113  	}
   114  
   115  	// We generate on a subcommand so we have both subcommands and parents
   116  	buf := new(bytes.Buffer)
   117  	if err := GenMan(echoCmd, header, buf); err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	output := buf.String()
   121  
   122  	unexpected := translate("#HISTORY")
   123  	checkStringOmits(t, output, unexpected)
   124  	unexpected = translate("Auto generated by spf13/cobra")
   125  	checkStringOmits(t, output, unexpected)
   126  }
   127  
   128  func TestGenManSeeAlso(t *testing.T) {
   129  	rootCmd := &cobra.Command{Use: "root", Run: emptyRun}
   130  	aCmd := &cobra.Command{Use: "aaa", Run: emptyRun, Hidden: true} // #229
   131  	bCmd := &cobra.Command{Use: "bbb", Run: emptyRun}
   132  	cCmd := &cobra.Command{Use: "ccc", Run: emptyRun}
   133  	rootCmd.AddCommand(aCmd, bCmd, cCmd)
   134  
   135  	buf := new(bytes.Buffer)
   136  	header := &GenManHeader{}
   137  	if err := GenMan(rootCmd, header, buf); err != nil {
   138  		t.Fatal(err)
   139  	}
   140  	scanner := bufio.NewScanner(buf)
   141  
   142  	if err := assertLineFound(scanner, ".SH SEE ALSO"); err != nil {
   143  		t.Fatalf("Couldn't find SEE ALSO section header: %v", err)
   144  	}
   145  	if err := assertNextLineEquals(scanner, ".PP"); err != nil {
   146  		t.Fatalf("First line after SEE ALSO wasn't break-indent: %v", err)
   147  	}
   148  	if err := assertNextLineEquals(scanner, `\fBroot-bbb(1)\fP, \fBroot-ccc(1)\fP`); err != nil {
   149  		t.Fatalf("Second line after SEE ALSO wasn't correct: %v", err)
   150  	}
   151  }
   152  
   153  func TestManPrintFlagsHidesShortDeprecated(t *testing.T) {
   154  	c := &cobra.Command{}
   155  	c.Flags().StringP("foo", "f", "default", "Foo flag")
   156  	assertNoErr(t, c.Flags().MarkShorthandDeprecated("foo", "don't use it no more"))
   157  
   158  	buf := new(bytes.Buffer)
   159  	manPrintFlags(buf, c.Flags())
   160  
   161  	got := buf.String()
   162  	expected := "**--foo**=\"default\"\n\tFoo flag\n\n"
   163  	if got != expected {
   164  		t.Errorf("Expected %v, got %v", expected, got)
   165  	}
   166  }
   167  
   168  func TestGenManTree(t *testing.T) {
   169  	c := &cobra.Command{Use: "do [OPTIONS] arg1 arg2"}
   170  	header := &GenManHeader{Section: "2"}
   171  	tmpdir, err := ioutil.TempDir("", "test-gen-man-tree")
   172  	if err != nil {
   173  		t.Fatalf("Failed to create tmpdir: %s", err.Error())
   174  	}
   175  	defer os.RemoveAll(tmpdir)
   176  
   177  	if err := GenManTree(c, header, tmpdir); err != nil {
   178  		t.Fatalf("GenManTree failed: %s", err.Error())
   179  	}
   180  
   181  	if _, err := os.Stat(filepath.Join(tmpdir, "do.2")); err != nil {
   182  		t.Fatalf("Expected file 'do.2' to exist")
   183  	}
   184  
   185  	if header.Title != "" {
   186  		t.Fatalf("Expected header.Title to be unmodified")
   187  	}
   188  }
   189  
   190  func assertLineFound(scanner *bufio.Scanner, expectedLine string) error {
   191  	for scanner.Scan() {
   192  		line := scanner.Text()
   193  		if line == expectedLine {
   194  			return nil
   195  		}
   196  	}
   197  
   198  	if err := scanner.Err(); err != nil {
   199  		return fmt.Errorf("scan failed: %s", err)
   200  	}
   201  
   202  	return fmt.Errorf("hit EOF before finding %v", expectedLine)
   203  }
   204  
   205  func assertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error {
   206  	if scanner.Scan() {
   207  		line := scanner.Text()
   208  		if line == expectedLine {
   209  			return nil
   210  		}
   211  		return fmt.Errorf("got %v, not %v", line, expectedLine)
   212  	}
   213  
   214  	if err := scanner.Err(); err != nil {
   215  		return fmt.Errorf("scan failed: %v", err)
   216  	}
   217  
   218  	return fmt.Errorf("hit EOF before finding %v", expectedLine)
   219  }
   220  
   221  func BenchmarkGenManToFile(b *testing.B) {
   222  	file, err := ioutil.TempFile("", "")
   223  	if err != nil {
   224  		b.Fatal(err)
   225  	}
   226  	defer os.Remove(file.Name())
   227  	defer file.Close()
   228  
   229  	b.ResetTimer()
   230  	for i := 0; i < b.N; i++ {
   231  		if err := GenMan(rootCmd, nil, file); err != nil {
   232  			b.Fatal(err)
   233  		}
   234  	}
   235  }
   236  

View as plain text