mirror of
https://github.com/golang/go
synced 2024-11-18 14:44:41 -07:00
ce1291533b
The link of the function declaration part is unnecessary because it points to the same place. Removed the link of the function declaration part. "IdentMode" has been removed since it is no longer used. Fixes golang/go#20269 Change-Id: I6399899947e46dc84c5432c1d645f6d96b7db4f6 Reviewed-on: https://go-review.googlesource.com/42892 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
293 lines
7.5 KiB
Go
293 lines
7.5 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package godoc
|
|
|
|
import (
|
|
"bytes"
|
|
"go/parser"
|
|
"go/token"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestPkgLinkFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
path string
|
|
want string
|
|
}{
|
|
{"/src/fmt", "pkg/fmt"},
|
|
{"src/fmt", "pkg/fmt"},
|
|
{"/fmt", "pkg/fmt"},
|
|
{"fmt", "pkg/fmt"},
|
|
} {
|
|
if got := pkgLinkFunc(tc.path); got != tc.want {
|
|
t.Errorf("pkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSrcPosLinkFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
src string
|
|
line int
|
|
low int
|
|
high int
|
|
want string
|
|
}{
|
|
{"/src/fmt/print.go", 42, 30, 50, "/src/fmt/print.go?s=30:50#L32"},
|
|
{"/src/fmt/print.go", 2, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
|
|
{"/src/fmt/print.go", 2, 0, 0, "/src/fmt/print.go#L2"},
|
|
{"/src/fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
|
|
{"/src/fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
|
|
{"fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
|
|
{"fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
|
|
} {
|
|
if got := srcPosLinkFunc(tc.src, tc.line, tc.low, tc.high); got != tc.want {
|
|
t.Errorf("srcLinkFunc(%v, %v, %v, %v) = %v; want %v", tc.src, tc.line, tc.low, tc.high, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSrcLinkFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
src string
|
|
want string
|
|
}{
|
|
{"/src/fmt/print.go", "/src/fmt/print.go"},
|
|
{"src/fmt/print.go", "/src/fmt/print.go"},
|
|
{"/fmt/print.go", "/src/fmt/print.go"},
|
|
{"fmt/print.go", "/src/fmt/print.go"},
|
|
} {
|
|
if got := srcLinkFunc(tc.src); got != tc.want {
|
|
t.Errorf("srcLinkFunc(%v) = %v; want %v", tc.src, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestQueryLinkFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
src string
|
|
query string
|
|
line int
|
|
want string
|
|
}{
|
|
{"/src/fmt/print.go", "Sprintf", 33, "/src/fmt/print.go?h=Sprintf#L33"},
|
|
{"/src/fmt/print.go", "Sprintf", 0, "/src/fmt/print.go?h=Sprintf"},
|
|
{"src/fmt/print.go", "EOF", 33, "/src/fmt/print.go?h=EOF#L33"},
|
|
{"src/fmt/print.go", "a%3f+%26b", 1, "/src/fmt/print.go?h=a%3f+%26b#L1"},
|
|
} {
|
|
if got := queryLinkFunc(tc.src, tc.query, tc.line); got != tc.want {
|
|
t.Errorf("queryLinkFunc(%v, %v, %v) = %v; want %v", tc.src, tc.query, tc.line, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDocLinkFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
src string
|
|
ident string
|
|
want string
|
|
}{
|
|
{"fmt", "Sprintf", "/pkg/fmt/#Sprintf"},
|
|
{"fmt", "EOF", "/pkg/fmt/#EOF"},
|
|
} {
|
|
if got := docLinkFunc(tc.src, tc.ident); got != tc.want {
|
|
t.Errorf("docLinkFunc(%v, %v) = %v; want %v", tc.src, tc.ident, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSanitizeFunc(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
src string
|
|
want string
|
|
}{
|
|
{},
|
|
{"foo", "foo"},
|
|
{"func f()", "func f()"},
|
|
{"func f(a int,)", "func f(a int)"},
|
|
{"func f(a int,\n)", "func f(a int)"},
|
|
{"func f(\n\ta int,\n\tb int,\n\tc int,\n)", "func f(a int, b int, c int)"},
|
|
{" ( a, b, c ) ", "(a, b, c)"},
|
|
{"( a, b, c int, foo bar , )", "(a, b, c int, foo bar)"},
|
|
{"{ a, b}", "{a, b}"},
|
|
{"[ a, b]", "[a, b]"},
|
|
} {
|
|
if got := sanitizeFunc(tc.src); got != tc.want {
|
|
t.Errorf("sanitizeFunc(%v) = %v; want %v", tc.src, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test that we add <span id="StructName.FieldName"> elements
|
|
// to the HTML of struct fields.
|
|
func TestStructFieldsIDAttributes(t *testing.T) {
|
|
got := linkifySource(t, []byte(`
|
|
package foo
|
|
|
|
type T struct {
|
|
NoDoc string
|
|
|
|
// Doc has a comment.
|
|
Doc string
|
|
|
|
// Opt, if non-nil, is an option.
|
|
Opt *int
|
|
|
|
// Опция - другое поле.
|
|
Опция bool
|
|
}
|
|
`))
|
|
want := `type T struct {
|
|
<span id="T.NoDoc"></span>NoDoc <a href="/pkg/builtin/#string">string</a>
|
|
|
|
<span id="T.Doc"></span><span class="comment">// Doc has a comment.</span>
|
|
Doc <a href="/pkg/builtin/#string">string</a>
|
|
|
|
<span id="T.Opt"></span><span class="comment">// Opt, if non-nil, is an option.</span>
|
|
Opt *<a href="/pkg/builtin/#int">int</a>
|
|
|
|
<span id="T.Опция"></span><span class="comment">// Опция - другое поле.</span>
|
|
Опция <a href="/pkg/builtin/#bool">bool</a>
|
|
}`
|
|
if got != want {
|
|
t.Errorf("got: %s\n\nwant: %s\n", got, want)
|
|
}
|
|
}
|
|
|
|
// Test that we add <span id="ConstName"> elements to the HTML
|
|
// of definitions in const and var specs.
|
|
func TestValueSpecIDAttributes(t *testing.T) {
|
|
got := linkifySource(t, []byte(`
|
|
package foo
|
|
|
|
const (
|
|
NoDoc string = "NoDoc"
|
|
|
|
// Doc has a comment
|
|
Doc = "Doc"
|
|
|
|
NoVal
|
|
)`))
|
|
want := `const (
|
|
<span id="NoDoc">NoDoc</span> <a href="/pkg/builtin/#string">string</a> = "NoDoc"
|
|
|
|
<span class="comment">// Doc has a comment</span>
|
|
<span id="Doc">Doc</span> = "Doc"
|
|
|
|
<span id="NoVal">NoVal</span>
|
|
)`
|
|
if got != want {
|
|
t.Errorf("got: %s\n\nwant: %s\n", got, want)
|
|
}
|
|
}
|
|
|
|
func TestCompositeLitLinkFields(t *testing.T) {
|
|
got := linkifySource(t, []byte(`
|
|
package foo
|
|
|
|
type T struct {
|
|
X int
|
|
}
|
|
|
|
var S T = T{X: 12}`))
|
|
want := `type T struct {
|
|
<span id="T.X"></span>X <a href="/pkg/builtin/#int">int</a>
|
|
}
|
|
var <span id="S">S</span> <a href="#T">T</a> = <a href="#T">T</a>{<a href="#T.X">X</a>: 12}`
|
|
if got != want {
|
|
t.Errorf("got: %s\n\nwant: %s\n", got, want)
|
|
}
|
|
}
|
|
|
|
func TestFuncDeclNotLink(t *testing.T) {
|
|
// Function.
|
|
got := linkifySource(t, []byte(`
|
|
package http
|
|
|
|
func Get(url string) (resp *Response, err error)`))
|
|
want := `func Get(url <a href="/pkg/builtin/#string">string</a>) (resp *<a href="#Response">Response</a>, err <a href="/pkg/builtin/#error">error</a>)`
|
|
if got != want {
|
|
t.Errorf("got: %s\n\nwant: %s\n", got, want)
|
|
}
|
|
|
|
// Method.
|
|
got = linkifySource(t, []byte(`
|
|
package http
|
|
|
|
func (h Header) Get(key string) string`))
|
|
want = `func (h <a href="#Header">Header</a>) Get(key <a href="/pkg/builtin/#string">string</a>) <a href="/pkg/builtin/#string">string</a>`
|
|
if got != want {
|
|
t.Errorf("got: %s\n\nwant: %s\n", got, want)
|
|
}
|
|
}
|
|
|
|
func linkifySource(t *testing.T, src []byte) string {
|
|
p := &Presentation{
|
|
DeclLinks: true,
|
|
}
|
|
fset := token.NewFileSet()
|
|
af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var buf bytes.Buffer
|
|
pi := &PageInfo{
|
|
FSet: fset,
|
|
}
|
|
sep := ""
|
|
for _, decl := range af.Decls {
|
|
buf.WriteString(sep)
|
|
sep = "\n"
|
|
buf.WriteString(p.node_htmlFunc(pi, decl, true))
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
func TestScanIdentifier(t *testing.T) {
|
|
tests := []struct {
|
|
in, want string
|
|
}{
|
|
{"foo bar", "foo"},
|
|
{"foo/bar", "foo"},
|
|
{" foo", ""},
|
|
{"фоо", "фоо"},
|
|
{"f123", "f123"},
|
|
{"123f", ""},
|
|
}
|
|
for _, tt := range tests {
|
|
got := scanIdentifier([]byte(tt.in))
|
|
if string(got) != tt.want {
|
|
t.Errorf("scanIdentifier(%q) = %q; want %q", tt.in, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestReplaceLeadingIndentation(t *testing.T) {
|
|
oldIndent := strings.Repeat(" ", 2)
|
|
newIndent := strings.Repeat(" ", 4)
|
|
tests := []struct {
|
|
src, want string
|
|
}{
|
|
{" foo\n bar\n baz", " foo\n bar\n baz"},
|
|
{" '`'\n '`'\n", " '`'\n '`'\n"},
|
|
{" '\\''\n '`'\n", " '\\''\n '`'\n"},
|
|
{" \"`\"\n \"`\"\n", " \"`\"\n \"`\"\n"},
|
|
{" `foo\n bar`", " `foo\n bar`"},
|
|
{" `foo\\`\n bar", " `foo\\`\n bar"},
|
|
{" '\\`'`foo\n bar", " '\\`'`foo\n bar"},
|
|
{
|
|
" if true {\n foo := `One\n \tTwo\nThree`\n }\n",
|
|
" if true {\n foo := `One\n \tTwo\n Three`\n }\n",
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
if got := replaceLeadingIndentation(tc.src, oldIndent, newIndent); got != tc.want {
|
|
t.Errorf("replaceLeadingIndentation:\n%v\n---\nhave:\n%v\n---\nwant:\n%v\n",
|
|
tc.src, got, tc.want)
|
|
}
|
|
}
|
|
}
|