internal/godoc/dochtml: compare with golden

Add a comparison with a golden file to the test, for
more thorough coverage.

Delete tests that are obsoleted by having a golden.

Factor out golden comparison to a separate package.

For golang/go#40850

Change-Id: Iac7b4c0e1c4aadad690d8d5118a6861408614aa2
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/313030
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
This commit is contained in:
Jonathan Amsterdam 2021-04-23 08:44:32 -04:00
Родитель 22d7146983
Коммит 750994b36d
5 изменённых файлов: 858 добавлений и 89 удалений

Просмотреть файл

@ -10,12 +10,11 @@ import (
"go/ast"
"go/token"
"io"
"io/ioutil"
"path/filepath"
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/pkgsite/internal/testing/testhelper"
)
var update = flag.Bool("update", false, "update goldens instead of checking against them")
@ -57,30 +56,7 @@ func testGenerate(t *testing.T, name string, x interface{}) {
t.Fatal(err)
}
got := buf.String()
if *update {
writeGolden(t, name, got)
} else {
want := readGolden(t, name)
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("%s: mismatch (-want, +got):\n%s", name, diff)
}
}
}
func writeGolden(t *testing.T, name string, data string) {
filename := filepath.Join("testdata", name+".go")
if err := ioutil.WriteFile(filename, []byte(data), 0644); err != nil {
t.Fatal(err)
}
t.Logf("wrote %s", filename)
}
func readGolden(t *testing.T, name string) string {
data, err := ioutil.ReadFile(filepath.Join("testdata", name+".go"))
if err != nil {
t.Fatal(err)
}
return string(data)
testhelper.CompareWithGolden(t, got, name+".go", *update)
}
func TestExportedFields(t *testing.T) {

Просмотреть файл

@ -7,6 +7,9 @@ package dochtml
import (
"bytes"
"context"
"flag"
"fmt"
"go/ast"
"go/parser"
"go/token"
@ -22,10 +25,13 @@ import (
"golang.org/x/pkgsite/internal/godoc/dochtml/internal/render"
"golang.org/x/pkgsite/internal/godoc/internal/doc"
"golang.org/x/pkgsite/internal/testing/htmlcheck"
"golang.org/x/pkgsite/internal/testing/testhelper"
)
var templateSource = template.TrustedSourceFromConstant("../../../content/static/html/doc")
var update = flag.Bool("update", false, "update goldens instead of checking against them")
var (
in = htmlcheck.In
hasAttr = htmlcheck.HasAttr
@ -41,27 +47,28 @@ var testRenderOptions = RenderOptions{
}
func TestRenderParts(t *testing.T) {
LoadTemplates(templateSource)
fset, d := mustLoadPackage("everydecl")
ctx := context.Background()
LoadTemplates(templateSource)
fset, d := mustLoadPackage("everydecl")
parts, err := Render(ctx, fset, d, testRenderOptions)
if err != nil {
t.Fatal(err)
}
compareWithGolden(t, parts, "everydecl", *update)
fset2, d2 := mustLoadPackage("deprecated")
parts2, err := Render(ctx, fset2, d2, testRenderOptions)
if err != nil {
t.Fatal(err)
}
compareWithGolden(t, parts2, "deprecated", *update)
bodyDoc, err := html.Parse(strings.NewReader(parts.Body.String()))
if err != nil {
t.Fatal(err)
}
sidenavDoc, err := html.Parse(strings.NewReader(parts.Outline.String()))
if err != nil {
t.Fatal(err)
}
mobileDoc, err := html.Parse(strings.NewReader(parts.MobileOutline.String()))
if err != nil {
t.Fatal(err)
}
// Check that there are no duplicate id attributes.
t.Run("duplicate ids", func(t *testing.T) {
testDuplicateIDs(t, bodyDoc)
@ -71,31 +78,6 @@ func TestRenderParts(t *testing.T) {
testIDsAndKinds(t, bodyDoc)
})
checker := in(".Documentation-note",
in("h3", hasAttr("id", "pkg-note-BUG"), hasExactText("Bugs ¶")),
in("a", hasHref("#pkg-note-BUG")))
if err := checker(bodyDoc); err != nil {
t.Errorf("note check: %v", err)
}
checker = in(".Documentation-index",
in(".Documentation-indexNote", in("a", hasHref("#pkg-note-BUG"), hasExactText("Bugs"))))
if err := checker(bodyDoc); err != nil {
t.Errorf("note check: %v", err)
}
checker = in(".DocNav-notes",
in("#nav-group-notes", in("li", in("a", hasHref("#pkg-note-BUG"), hasText("Bugs")))))
if err := checker(sidenavDoc); err != nil {
t.Errorf("note check: %v", err)
}
checker = in("",
in("optgroup[label=Notes]", in("option", hasAttr("value", "pkg-note-BUG"), hasExactText("Bugs"))))
if err := checker(mobileDoc); err != nil {
t.Errorf("note check: %v", err)
}
wantLinks := []render.Link{
{Href: "https://go.googlesource.com/pkgsite", Text: "pkgsite repo"},
{Href: "https://play-with-go.dev", Text: "Play with Go"},
@ -105,6 +87,11 @@ func TestRenderParts(t *testing.T) {
}
}
func compareWithGolden(t *testing.T, parts *Parts, name string, update bool) {
got := fmt.Sprintf("%s\n----\n%s\n----\n%s\n", parts.Body, parts.Outline, parts.MobileOutline)
testhelper.CompareWithGolden(t, got, name+".golden", update)
}
func TestExampleRender(t *testing.T) {
LoadTemplates(templateSource)
ctx := context.Background()
@ -353,33 +340,6 @@ func TestVersionedPkgPath(t *testing.T) {
}
}
func TestDeprecated(t *testing.T) {
LoadTemplates(templateSource)
ctx := context.Background()
fset, d := mustLoadPackage("deprecated")
parts, err := Render(ctx, fset, d, testRenderOptions)
if err != nil {
t.Fatal(err)
}
// In package deprecated, all non-deprecated symbols begin with "Good" and
// all deprecated ones begin with "Bad".
// There is one const, var, func and type of each.
// The outline only has functions and types, so we should see two "Good"s and no "Bad"s.
outlineString := parts.Outline.String()
for _, want := range []string{"GoodF()", "type GoodT", "GoodM", "NewGoodTGood()"} {
if !strings.Contains(outlineString, want) {
t.Errorf("outline does not have %q but should", want)
}
}
for _, notWant := range []string{"BadF()", "type BadT", "BadM()", "NewGoodTBad()"} {
if strings.Contains(outlineString, notWant) {
t.Errorf("outline has %q but shouldn't", notWant)
}
}
}
func testDuplicateIDs(t *testing.T, htmlDoc *html.Node) {
idCounts := map[string]int{}
walk(htmlDoc, func(n *html.Node) {

330
internal/godoc/dochtml/testdata/deprecated.golden поставляемый Normal file
Просмотреть файл

@ -0,0 +1,330 @@
<div class="Documentation-content js-docContent"> <section class="Documentation-overview">
<h3 tabindex="-1" id="pkg-overview" class="Documentation-overviewHeader">Overview <a href="#pkg-overview">¶</a></h3>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>Package deprecated has some deprecated symbols.
</p>
</section><section class="Documentation-index">
<h3 id="pkg-index" class="Documentation-indexHeader">Index <a href="#pkg-index">¶</a></h3>
<ul class="Documentation-indexList">
<li class="Documentation-indexConstants"><a href="#pkg-constants">Constants</a></li>
<li class="Documentation-indexVariables"><a href="#pkg-variables">Variables</a></li>
<li class="Documentation-indexFunction">
<a href="#BadF">func BadF()</a>
</li>
<li class="Documentation-indexFunction">
<a href="#GoodF">func GoodF()</a>
</li>
<li class="Documentation-indexType"><a href="#BadT">type BadT</a></li>
<li class="Documentation-indexType"><a href="#GoodT">type GoodT</a></li>
<li><ul class="Documentation-indexTypeFunctions">
<li><a href="#NewGoodTBad">func NewGoodTBad() GoodT</a></li>
<li><a href="#NewGoodTGood">func NewGoodTGood() GoodT</a></li>
</ul></li>
<li><ul class="Documentation-indexTypeMethods">
<li><a href="#GoodT.BadM">func (GoodT) BadM()</a></li>
<li><a href="#GoodT.GoodM">func (GoodT) GoodM()</a></li>
</ul></li>
</ul>
</section><h3 tabindex="-1" id="pkg-constants" class="Documentation-constantsHeader">Constants <a href="#pkg-constants">¶</a></h3>
<section class="Documentation-constants">
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="BadC" data-kind="constant">const BadC = 2</span></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>BadC is bad.
Deprecated: use GoodC.
</p>
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="GoodC" data-kind="constant">const GoodC = 1</span></pre>
</div>
</section>
<h3 tabindex="-1" id="pkg-variables" class="Documentation-variablesHeader">Variables <a href="#pkg-variables">¶</a></h3>
<section class="Documentation-variables">
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="BadV" data-kind="variable">var BadV = 2 <span class="comment">// Deprecated: use GoodV.</span>
</span></pre>
</div>
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="GoodV" data-kind="variable">var GoodV = 1</span></pre>
</div>
</section>
<h3 tabindex="-1" id="pkg-functions" class="Documentation-functionsHeader">Functions <a href="#pkg-functions">¶</a></h3>
<section class="Documentation-functions"><div class="Documentation-function"><h4 tabindex="-1" id="BadF" data-kind="function" class="Documentation-functionHeader">
<span>func <a class="Documentation-source" href="src">BadF</a> <a class="Documentation-idLink" href="#BadF">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func BadF()</pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>BadF is bad.
Deprecated: use GoodF.
</p>
</div><div class="Documentation-function"><h4 tabindex="-1" id="GoodF" data-kind="function" class="Documentation-functionHeader">
<span>func <a class="Documentation-source" href="src">GoodF</a> <a class="Documentation-idLink" href="#GoodF">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func GoodF()</pre>
</div>
</div></section>
<h3 tabindex="-1" id="pkg-types" class="Documentation-typesHeader">Types <a href="#pkg-types">¶</a></h3>
<section class="Documentation-types"><div class="Documentation-type"><h4 tabindex="-1" id="BadT" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">BadT</a> <a class="Documentation-idLink" href="#BadT">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type BadT <a href="/builtin#int">int</a></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>BadT is bad.
Deprecated: use GoodT.
Don&#39;t use this.
</p>
</div><div class="Documentation-type"><h4 tabindex="-1" id="GoodT" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">GoodT</a> <a class="Documentation-idLink" href="#GoodT">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type GoodT <a href="/builtin#int">int</a></pre>
</div>
<div class="Documentation-typeFunc"><h4 tabindex="-1" id="NewGoodTBad" data-kind="function" class="Documentation-typeFuncHeader">
<span>func <a class="Documentation-source" href="src">NewGoodTBad</a> <a class="Documentation-idLink" href="#NewGoodTBad">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func NewGoodTBad() <a href="#GoodT">GoodT</a></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>NewGoodTBad is bad.
Deprecated: use NewGoodTGood.
</p>
</div><div class="Documentation-typeFunc"><h4 tabindex="-1" id="NewGoodTGood" data-kind="function" class="Documentation-typeFuncHeader">
<span>func <a class="Documentation-source" href="src">NewGoodTGood</a> <a class="Documentation-idLink" href="#NewGoodTGood">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func NewGoodTGood() <a href="#GoodT">GoodT</a></pre>
</div>
</div><div class="Documentation-typeMethod"><h4 tabindex="-1" id="GoodT.BadM" data-kind="method" class="Documentation-typeMethodHeader">
<span>func (GoodT) <a class="Documentation-source" href="src">BadM</a> <a class="Documentation-idLink" href="#GoodT.BadM">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func (<a href="#GoodT">GoodT</a>) BadM()</pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>BadM is bad.
Deprecated: use GoodM.
</p>
</div><div class="Documentation-typeMethod"><h4 tabindex="-1" id="GoodT.GoodM" data-kind="method" class="Documentation-typeMethodHeader">
<span>func (GoodT) <a class="Documentation-source" href="src">GoodM</a> <a class="Documentation-idLink" href="#GoodT.GoodM">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func (<a href="#GoodT">GoodT</a>) GoodM()</pre>
</div>
</div></div></section></div>
----
<ul role="group" id="doc-outline">
<li role="none">
<a href="#pkg-overview" role="treeitem" aria-level="2" tabindex="-1">Overview</a>
</li>
<li class="DocNav-overview" role="none">
<a href="#pkg-index" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-index"
>
Index
</a>
</li>
<li class="DocNav-constants" role="none">
<a href="#pkg-constants" role="treeitem" aria-level="2" tabindex="-1">Constants</a>
</li>
<li class="DocNav-variables" role="none">
<a href="#pkg-variables" role="treeitem" aria-level="2" tabindex="-1">Variables</a>
</li>
<li class="DocNav-functions" role="none">
<a href="#pkg-functions" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-functions"
aria-expanded="false">
Functions
</a>
<ul role="group" id="nav-group-functions">
<li role="none">
<a href="#GoodF" role="treeitem" aria-level="3" tabindex="-1"
title="GoodF()">
GoodF()
</a>
</li>
</ul>
</li>
<li class="DocNav-types" role="none">
<a href="#pkg-types" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-types"
aria-expanded="false">
Types
</a>
<ul role="group" id="nav-group-types">
<li role="none">
<a href="#GoodT" role="treeitem" aria-expanded="false" aria-level="3" tabindex="-1"
data-aria-owns="nav.group.GoodT">
type GoodT
</a>
<ul role="group" id="nav.group.GoodT">
<li role="none">
<a href="#NewGoodTGood" role="treeitem" aria-level="4" tabindex="-1"
title="NewGoodTGood()">
NewGoodTGood()
</a>
</li>
<li role="none">
<a href="#GoodT.GoodM" role="treeitem" aria-level="4" tabindex="-1"
title="GoodM()">
GoodM()
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
----
<optgroup label="Documentation">
<option value="pkg-overview">Overview</option>
<option value="pkg-index">Index</option>
<option value="pkg-constants">Constants</option>
<option value="pkg-variables">Variables</option>
</optgroup>
<optgroup label="Functions">
<option value="BadF">BadF()</option>
<option value="GoodF">GoodF()</option>
</optgroup>
<optgroup label="Types">
<option value="BadT">type BadT</option>
<option value="GoodT">type GoodT</option>
<option value="NewGoodTBad">NewGoodTBad()</option>
<option value="NewGoodTGood">NewGoodTGood()</option>
<option value="GoodT.BadM">BadM()</option>
<option value="GoodT.GoodM">GoodM()</option>
</optgroup>

473
internal/godoc/dochtml/testdata/everydecl.golden поставляемый Normal file
Просмотреть файл

@ -0,0 +1,473 @@
<div class="Documentation-content js-docContent"> <section class="Documentation-overview">
<h3 tabindex="-1" id="pkg-overview" class="Documentation-overviewHeader">Overview <a href="#pkg-overview">¶</a></h3>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>Package everydecl has every form of declaration known to dochtml.
It is designed to test that the generated HTML has the right id and data-kind
attributes.
</p>
</section><section class="Documentation-index">
<h3 id="pkg-index" class="Documentation-indexHeader">Index <a href="#pkg-index">¶</a></h3>
<ul class="Documentation-indexList">
<li class="Documentation-indexConstants"><a href="#pkg-constants">Constants</a></li>
<li class="Documentation-indexVariables"><a href="#pkg-variables">Variables</a></li>
<li class="Documentation-indexFunction">
<a href="#F">func F()</a>
</li>
<li class="Documentation-indexType"><a href="#A">type A</a></li>
<li class="Documentation-indexType"><a href="#B">type B</a></li>
<li class="Documentation-indexType"><a href="#I1">type I1</a></li>
<li class="Documentation-indexType"><a href="#I2">type I2</a></li>
<li class="Documentation-indexType"><a href="#S1">type S1</a></li>
<li class="Documentation-indexType"><a href="#S2">type S2</a></li>
<li class="Documentation-indexType"><a href="#T">type T</a></li>
<li><ul class="Documentation-indexTypeFunctions">
<li><a href="#TF">func TF() T</a></li>
</ul></li>
<li><ul class="Documentation-indexTypeMethods">
<li><a href="#T.M">func (T) M()</a></li>
</ul></li>
<li class="Documentation-indexNote"><a href="#pkg-note-BUG">Bugs</a></li></ul>
</section><h3 tabindex="-1" id="pkg-constants" class="Documentation-constantsHeader">Constants <a href="#pkg-constants">¶</a></h3>
<section class="Documentation-constants">
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="C" data-kind="constant">const C = 1</span></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>const
</p>
</section>
<h3 tabindex="-1" id="pkg-variables" class="Documentation-variablesHeader">Variables <a href="#pkg-variables">¶</a></h3>
<section class="Documentation-variables">
<div class="Documentation-declaration">
<span class="Documentation-declarationLink"><a class="Documentation-source" href="src">View Source</a></span>
<pre><span id="V" data-kind="variable">var V = 2</span></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>var
</p>
</section>
<h3 tabindex="-1" id="pkg-functions" class="Documentation-functionsHeader">Functions <a href="#pkg-functions">¶</a></h3>
<section class="Documentation-functions"><div class="Documentation-function"><h4 tabindex="-1" id="F" data-kind="function" class="Documentation-functionHeader">
<span>func <a class="Documentation-source" href="src">F</a> <a class="Documentation-idLink" href="#F">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func F()</pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>func
</p>
</div></section>
<h3 tabindex="-1" id="pkg-types" class="Documentation-typesHeader">Types <a href="#pkg-types">¶</a></h3>
<section class="Documentation-types"><div class="Documentation-type"><h4 tabindex="-1" id="A" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">A</a> <a class="Documentation-idLink" href="#A">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type A <a href="/builtin#int">int</a></pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="B" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">B</a> <a class="Documentation-idLink" href="#B">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type B <a href="/builtin#bool">bool</a></pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="I1" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">I1</a> <a class="Documentation-idLink" href="#I1">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type I1 interface {
<span id="I1.M1" data-kind="method"> M1()
</span>}</pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="I2" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">I2</a> <a class="Documentation-idLink" href="#I2">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type I2 interface {
<a href="#I1">I1</a> <span class="comment">// embedded interface; should not have an id</span>
<span id="I2.M2" data-kind="method"> M2()
</span>}</pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="S1" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">S1</a> <a class="Documentation-idLink" href="#S1">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type S1 struct {
<span id="S1.F" data-kind="field"> F <a href="/builtin#int">int</a> <span class="comment">// field</span>
</span>}</pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="S2" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">S2</a> <a class="Documentation-idLink" href="#S2">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type S2 struct {
<span id="S2.S1" data-kind="field"> <a href="#S1">S1</a> <span class="comment">// embedded struct; should have an id</span>
</span><span id="S2.G" data-kind="field"> G <a href="/builtin#int">int</a>
</span>}</pre>
</div>
</div><div class="Documentation-type"><h4 tabindex="-1" id="T" data-kind="type" class="Documentation-typeHeader">
<span>type <a class="Documentation-source" href="src">T</a> <a class="Documentation-idLink" href="#T">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>type T <a href="/builtin#int">int</a></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>type
</p>
<div class="Documentation-typeConstant">
<div class="Documentation-declaration">
<pre><span id="CT" data-kind="constant">const CT <a href="#T">T</a> = 3</span></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>typeConstant
</p>
</div><div class="Documentation-typeVariable">
<div class="Documentation-declaration">
<pre><span id="VT" data-kind="variable">var VT <a href="#T">T</a></span></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>typeVariable
</p>
</div><div class="Documentation-typeFunc"><h4 tabindex="-1" id="TF" data-kind="function" class="Documentation-typeFuncHeader">
<span>func <a class="Documentation-source" href="src">TF</a> <a class="Documentation-idLink" href="#TF">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func TF() <a href="#T">T</a></pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>typeFunc
</p>
</div><div class="Documentation-typeMethod"><h4 tabindex="-1" id="T.M" data-kind="method" class="Documentation-typeMethodHeader">
<span>func (T) <a class="Documentation-source" href="src">M</a> <a class="Documentation-idLink" href="#T.M">¶</a></span>
<span class="Documentation-sinceVersion">
</span>
</h4>
<div class="Documentation-declaration">
<pre>func (<a href="#T">T</a>) M()</pre>
</div>
<div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>method
BUG(uid): this verifies that notes are rendered
</p>
</div></div></section><h3 tabindex="-1" id="pkg-notes" class="Documentation-notesHeader">Notes <a href="#pkg-notes">¶</a></h3>
<section class="Documentation-notes"><div class="Documentation-note">
<h3 tabindex="-1" id="pkg-note-BUG" class="Documentation-noteHeader">Bugs <a href="#pkg-note-BUG">¶</a></h3>
<ul class="Documentation-noteList" style="padding-left: 20px; list-style: initial;">
<li style="margin: 6px 0 6px 0;"><div role="navigation" aria-label="Table of Contents">
<ul class="Documentation-toc"></ul>
</div><p>this verifies that notes are rendered
</p></li></ul>
</div></section></div>
----
<ul role="group" id="doc-outline">
<li role="none">
<a href="#pkg-overview" role="treeitem" aria-level="2" tabindex="-1">Overview</a>
</li>
<li class="DocNav-overview" role="none">
<a href="#pkg-index" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-index"
>
Index
</a>
</li>
<li class="DocNav-constants" role="none">
<a href="#pkg-constants" role="treeitem" aria-level="2" tabindex="-1">Constants</a>
</li>
<li class="DocNav-variables" role="none">
<a href="#pkg-variables" role="treeitem" aria-level="2" tabindex="-1">Variables</a>
</li>
<li class="DocNav-functions" role="none">
<a href="#pkg-functions" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-functions"
aria-expanded="false">
Functions
</a>
<ul role="group" id="nav-group-functions">
<li role="none">
<a href="#F" role="treeitem" aria-level="3" tabindex="-1"
title="F()">
F()
</a>
</li>
</ul>
</li>
<li class="DocNav-types" role="none">
<a href="#pkg-types" role="treeitem" aria-level="2" tabindex="-1" aria-owns="nav-group-types"
aria-expanded="false">
Types
</a>
<ul role="group" id="nav-group-types">
<li role="none">
<a href="#A" role="treeitem" aria-level="3" tabindex="-1">
type A
</a>
</li>
<li role="none">
<a href="#B" role="treeitem" aria-level="3" tabindex="-1">
type B
</a>
</li>
<li role="none">
<a href="#I1" role="treeitem" aria-level="3" tabindex="-1">
type I1
</a>
</li>
<li role="none">
<a href="#I2" role="treeitem" aria-level="3" tabindex="-1">
type I2
</a>
</li>
<li role="none">
<a href="#S1" role="treeitem" aria-level="3" tabindex="-1">
type S1
</a>
</li>
<li role="none">
<a href="#S2" role="treeitem" aria-level="3" tabindex="-1">
type S2
</a>
</li>
<li role="none">
<a href="#T" role="treeitem" aria-expanded="false" aria-level="3" tabindex="-1"
data-aria-owns="nav.group.T">
type T
</a>
<ul role="group" id="nav.group.T">
<li role="none">
<a href="#TF" role="treeitem" aria-level="4" tabindex="-1"
title="TF()">
TF()
</a>
</li>
<li role="none">
<a href="#T.M" role="treeitem" aria-level="4" tabindex="-1"
title="M()">
M()
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="DocNav-notes" role="none">
<a href="#pkg-notes" role="treeitem" aria-expanded="false" aria-level="2" tabindex="-1"
aria-owns="nav-group-notes">
Notes
</a>
<ul role="group" id="nav-group-notes">
<li role="none">
<a href="#pkg-note-BUG" role="treeitem" aria-level="3" tabindex="-1">
Bugs
</a>
</li>
</ul>
</li>
</ul>
----
<optgroup label="Documentation">
<option value="pkg-overview">Overview</option>
<option value="pkg-index">Index</option>
<option value="pkg-constants">Constants</option>
<option value="pkg-variables">Variables</option>
</optgroup>
<optgroup label="Functions">
<option value="F">F()</option>
</optgroup>
<optgroup label="Types">
<option value="A">type A</option>
<option value="B">type B</option>
<option value="I1">type I1</option>
<option value="I2">type I2</option>
<option value="S1">type S1</option>
<option value="S2">type S2</option>
<option value="T">type T</option>
<option value="TF">TF()</option>
<option value="T.M">M()</option>
</optgroup>
<optgroup label="Notes">
<option value="pkg-note-BUG">Bugs</option>
</optgroup>

Просмотреть файл

@ -20,7 +20,9 @@ import (
"os"
"path/filepath"
"runtime"
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/pkgsite/internal/derrors"
)
@ -142,3 +144,31 @@ func CreateTestDirectory(files map[string]string) (_ string, err error) {
return tempDir, nil
}
func CompareWithGolden(t *testing.T, got, filename string, update bool) {
t.Helper()
if update {
writeGolden(t, filename, got)
} else {
want := readGolden(t, filename)
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("%s: mismatch (-want, +got):\n%s", filename, diff)
}
}
}
func writeGolden(t *testing.T, name string, data string) {
filename := filepath.Join("testdata", name)
if err := ioutil.WriteFile(filename, []byte(data), 0644); err != nil {
t.Fatal(err)
}
t.Logf("wrote %s", filename)
}
func readGolden(t *testing.T, name string) string {
data, err := ioutil.ReadFile(filepath.Join("testdata", name))
if err != nil {
t.Fatal(err)
}
return string(data)
}