github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/godoc/cmdline_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package godoc 6 7 import ( 8 "bytes" 9 "go/build" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "reflect" 14 "regexp" 15 "runtime" 16 "testing" 17 "text/template" 18 19 "golang.org/x/tools/godoc/vfs" 20 "golang.org/x/tools/godoc/vfs/mapfs" 21 ) 22 23 // setupGoroot creates temporary directory to act as GOROOT when running tests 24 // that depend upon the build package. It updates build.Default to point to the 25 // new GOROOT. 26 // It returns a function that can be called to reset build.Default and remove 27 // the temporary directory. 28 func setupGoroot(t *testing.T) (cleanup func()) { 29 var stdLib = map[string]string{ 30 "src/fmt/fmt.go": `// Package fmt implements formatted I/O. 31 package fmt 32 33 type Stringer interface { 34 String() string 35 } 36 `, 37 } 38 goroot, err := ioutil.TempDir("", "cmdline_test") 39 if err != nil { 40 t.Fatal(err) 41 } 42 origContext := build.Default 43 build.Default = build.Context{ 44 GOROOT: goroot, 45 Compiler: "gc", 46 } 47 for relname, contents := range stdLib { 48 name := filepath.Join(goroot, relname) 49 if err := os.MkdirAll(filepath.Dir(name), 0770); err != nil { 50 t.Fatal(err) 51 } 52 if err := ioutil.WriteFile(name, []byte(contents), 0770); err != nil { 53 t.Fatal(err) 54 } 55 } 56 57 return func() { 58 if err := os.RemoveAll(goroot); err != nil { 59 t.Log(err) 60 } 61 build.Default = origContext 62 } 63 } 64 65 func TestPaths(t *testing.T) { 66 cleanup := setupGoroot(t) 67 defer cleanup() 68 69 pres := &Presentation{ 70 pkgHandler: handlerServer{ 71 fsRoot: "/fsroot", 72 }, 73 } 74 fs := make(vfs.NameSpace) 75 76 absPath := "/foo/fmt" 77 if runtime.GOOS == "windows" { 78 absPath = `c:\foo\fmt` 79 } 80 81 for _, tc := range []struct { 82 desc string 83 path string 84 expAbs string 85 expRel string 86 }{ 87 { 88 "Absolute path", 89 absPath, 90 "/target", 91 "/target", 92 }, 93 { 94 "Local import", 95 "../foo/fmt", 96 "/target", 97 "/target", 98 }, 99 { 100 "Import", 101 "fmt", 102 "/target", 103 "fmt", 104 }, 105 { 106 "Default", 107 "unknownpkg", 108 "/fsroot/unknownpkg", 109 "unknownpkg", 110 }, 111 } { 112 abs, rel := paths(fs, pres, tc.path) 113 if abs != tc.expAbs || rel != tc.expRel { 114 t.Errorf("%s: paths(%q) = %s,%s; want %s,%s", tc.desc, tc.path, abs, rel, tc.expAbs, tc.expRel) 115 } 116 } 117 } 118 119 func TestMakeRx(t *testing.T) { 120 for _, tc := range []struct { 121 desc string 122 names []string 123 exp string 124 }{ 125 { 126 desc: "empty string", 127 names: []string{""}, 128 exp: `^$`, 129 }, 130 { 131 desc: "simple text", 132 names: []string{"a"}, 133 exp: `^a$`, 134 }, 135 { 136 desc: "two words", 137 names: []string{"foo", "bar"}, 138 exp: `^foo$|^bar$`, 139 }, 140 { 141 desc: "word & non-trivial", 142 names: []string{"foo", `ab?c`}, 143 exp: `^foo$|ab?c`, 144 }, 145 { 146 desc: "bad regexp", 147 names: []string{`(."`}, 148 exp: `(."`, 149 }, 150 } { 151 expRE, expErr := regexp.Compile(tc.exp) 152 if re, err := makeRx(tc.names); !reflect.DeepEqual(err, expErr) && !reflect.DeepEqual(re, expRE) { 153 t.Errorf("%s: makeRx(%v) = %q,%q; want %q,%q", tc.desc, tc.names, re, err, expRE, expErr) 154 } 155 } 156 } 157 158 func TestCommandLine(t *testing.T) { 159 cleanup := setupGoroot(t) 160 defer cleanup() 161 mfs := mapfs.New(map[string]string{ 162 "src/bar/bar.go": `// Package bar is an example. 163 package bar 164 `, 165 "src/foo/foo.go": `// Package foo. 166 package foo 167 168 // First function is first. 169 func First() { 170 } 171 172 // Second function is second. 173 func Second() { 174 } 175 `, 176 "src/gen/gen.go": `// Package gen 177 package gen 178 179 //line notgen.go:3 180 // F doc //line 1 should appear 181 // line 2 should appear 182 func F() 183 //line foo.go:100`, // no newline on end to check corner cases! 184 "src/vet/vet.go": `// Package vet 185 package vet 186 `, 187 "src/cmd/go/doc.go": `// The go command 188 package main 189 `, 190 "src/cmd/gofmt/doc.go": `// The gofmt command 191 package main 192 `, 193 "src/cmd/vet/vet.go": `// The vet command 194 package main 195 `, 196 }) 197 fs := make(vfs.NameSpace) 198 fs.Bind("/", mfs, "/", vfs.BindReplace) 199 c := NewCorpus(fs) 200 p := &Presentation{Corpus: c} 201 p.cmdHandler = handlerServer{ 202 p: p, 203 c: c, 204 pattern: "/cmd/", 205 fsRoot: "/src/cmd", 206 } 207 p.pkgHandler = handlerServer{ 208 p: p, 209 c: c, 210 pattern: "/pkg/", 211 fsRoot: "/src", 212 exclude: []string{"/src/cmd"}, 213 } 214 p.initFuncMap() 215 p.PackageText = template.Must(template.New("PackageText").Funcs(p.FuncMap()).Parse(`{{$info := .}}{{$filtered := .IsFiltered}}{{if $filtered}}{{range .PAst}}{{range .Decls}}{{node $info .}}{{end}}{{end}}{{else}}{{with .PAst}}{{range $filename, $ast := .}}{{$filename}}: 216 {{node $ $ast}}{{end}}{{end}}{{end}}{{with .PDoc}}{{if $.IsMain}}COMMAND {{.Doc}}{{else}}PACKAGE {{.Doc}}{{end}}{{with .Funcs}} 217 {{range .}}{{node $ .Decl}} 218 {{comment_text .Doc " " "\t"}}{{end}}{{end}}{{end}}`)) 219 220 for _, tc := range []struct { 221 desc string 222 args []string 223 exp string 224 err bool 225 }{ 226 { 227 desc: "standard package", 228 args: []string{"fmt"}, 229 exp: "PACKAGE Package fmt implements formatted I/O.\n", 230 }, 231 { 232 desc: "package", 233 args: []string{"bar"}, 234 exp: "PACKAGE Package bar is an example.\n", 235 }, 236 { 237 desc: "package w. filter", 238 args: []string{"foo", "First"}, 239 exp: "PACKAGE \nfunc First()\n First function is first.\n", 240 }, 241 { 242 desc: "package w. bad filter", 243 args: []string{"foo", "DNE"}, 244 exp: "PACKAGE ", 245 }, 246 { 247 desc: "source mode", 248 args: []string{"src/bar"}, 249 exp: "bar/bar.go:\n// Package bar is an example.\npackage bar\n", 250 }, 251 { 252 desc: "source mode w. filter", 253 args: []string{"src/foo", "Second"}, 254 exp: "// Second function is second.\nfunc Second() {\n}", 255 }, 256 { 257 desc: "package w. //line comments", 258 args: []string{"gen", "F"}, 259 exp: "PACKAGE \nfunc F()\n F doc //line 1 should appear line 2 should appear\n", 260 }, 261 { 262 desc: "command", 263 args: []string{"go"}, 264 exp: "COMMAND The go command\n", 265 }, 266 { 267 desc: "forced command", 268 args: []string{"cmd/gofmt"}, 269 exp: "COMMAND The gofmt command\n", 270 }, 271 { 272 desc: "bad arg", 273 args: []string{"doesnotexist"}, 274 err: true, 275 }, 276 { 277 desc: "both command and package", 278 args: []string{"vet"}, 279 exp: "use 'godoc cmd/vet' for documentation on the vet command \n\nPACKAGE Package vet\n", 280 }, 281 { 282 desc: "root directory", 283 args: []string{"/"}, 284 exp: "", 285 }, 286 } { 287 w := new(bytes.Buffer) 288 err := CommandLine(w, fs, p, tc.args) 289 if got, want := w.String(), tc.exp; got != want || tc.err == (err == nil) { 290 t.Errorf("%s: CommandLine(%v) = %q (%v); want %q (%v)", 291 tc.desc, tc.args, got, err, want, tc.err) 292 } 293 } 294 }