summaryrefslogtreecommitdiff
path: root/kythe/go/serving/xrefs/xrefs_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'kythe/go/serving/xrefs/xrefs_test.go')
-rw-r--r--kythe/go/serving/xrefs/xrefs_test.go603
1 files changed, 571 insertions, 32 deletions
diff --git a/kythe/go/serving/xrefs/xrefs_test.go b/kythe/go/serving/xrefs/xrefs_test.go
index 4f8b0cf65..6a65f76f7 100644
--- a/kythe/go/serving/xrefs/xrefs_test.go
+++ b/kythe/go/serving/xrefs/xrefs_test.go
@@ -20,6 +20,7 @@ import (
"bytes"
"context"
"sort"
+ "strconv"
"testing"
"kythe.io/kythe/go/services/xrefs"
@@ -32,6 +33,7 @@ import (
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
+ "google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/proto"
cpb "kythe.io/kythe/proto/common_go_proto"
@@ -136,7 +138,21 @@ var (
Fact: makeFactList(
"/kythe/node/kind", "record",
),
- DefinitionLocation: &srvpb.ExpandedAnchor{Ticket: "kythe:?path=def/location#defDoc"},
+ DefinitionLocation: &srvpb.ExpandedAnchor{
+ Ticket: "kythe:?path=def/location#defDoc",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 1,
+ LineNumber: 1,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 4,
+ LineNumber: 1,
+ ColumnOffset: 4,
+ },
+ },
+ },
}, {
Ticket: "kythe:#documentedBy",
Fact: makeFactList(
@@ -662,7 +678,7 @@ func TestDecorationsRefs(t *testing.T) {
References: true,
Filter: []string{"**"},
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
if len(reply.SourceText) != 0 {
t.Errorf("Unexpected source text: %q", string(reply.SourceText))
@@ -694,7 +710,7 @@ func TestDecorationsRefScopes(t *testing.T) {
References: true,
SemanticScopes: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := refs(span.NewNormalizer(d.File.Text), d.Decoration, d.FileInfo)
if err := testutil.DeepEqual(expected, reply.Reference); err != nil {
@@ -713,7 +729,7 @@ func TestDecorationsExtendsOverrides(t *testing.T) {
SemanticScopes: true,
TargetDefinitions: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expectedOverrides := map[string]*xpb.DecorationsReply_Overrides{
"kythe://c?lang=otpl?path=/a/path#map": &xpb.DecorationsReply_Overrides{
@@ -777,7 +793,7 @@ func TestDecorationsBuildConfig(t *testing.T) {
ExtendsOverrides: true,
TargetDefinitions: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
if err := testutil.DeepEqual([]*xpb.DecorationsReply_Reference{}, reply.Reference); err != nil {
t.Fatal(err)
@@ -792,7 +808,7 @@ func TestDecorationsBuildConfig(t *testing.T) {
ExtendsOverrides: true,
TargetDefinitions: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := refs(span.NewNormalizer(d.File.Text), d.Decoration[:1], d.FileInfo)
if err := testutil.DeepEqual(expected, reply.Reference); err != nil {
@@ -849,7 +865,7 @@ func TestDecorationsDirtyBuffer(t *testing.T) {
References: true,
Filter: []string{"**"},
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
if len(reply.SourceText) != 0 {
t.Errorf("Unexpected source text: %q", string(reply.SourceText))
@@ -933,7 +949,7 @@ func TestDecorationsEmpty(t *testing.T) {
},
References: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
if len(reply.Reference) > 0 {
t.Fatalf("Unexpected DecorationsReply: {%v}", reply)
@@ -948,7 +964,7 @@ func TestDecorationsSourceText(t *testing.T) {
Location: &xpb.Location{Ticket: expected.File.Ticket},
SourceText: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
if !bytes.Equal(reply.SourceText, expected.File.Text) {
t.Errorf("Expected source text %q; found %q", string(expected.File.Text), string(reply.SourceText))
@@ -966,7 +982,7 @@ func TestDecorationsGeneratedBy(t *testing.T) {
reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
Location: &xpb.Location{Ticket: "kythe://corpus?path=/some/proto.proto?root=generated"},
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := &xpb.DecorationsReply{
Location: &xpb.Location{Ticket: "kythe://corpus?path=/some/proto.proto?root=generated"},
@@ -990,7 +1006,7 @@ func TestDecorationsRevisions(t *testing.T) {
reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := &xpb.DecorationsReply{
Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
@@ -1014,7 +1030,7 @@ func TestDecorationsRevisions(t *testing.T) {
Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
References: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := &xpb.DecorationsReply{
Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
@@ -1071,7 +1087,7 @@ func TestDecorationsRevisions(t *testing.T) {
References: true,
TargetDefinitions: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := &xpb.DecorationsReply{
Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
@@ -1143,7 +1159,7 @@ func TestDecorationsDiagnostics(t *testing.T) {
Location: &xpb.Location{Ticket: d.File.Ticket},
Diagnostics: true,
})
- testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
expected := tbl.Decorations[1].Diagnostic
if err := testutil.DeepEqual(expected, reply.Diagnostic); err != nil {
@@ -1158,7 +1174,7 @@ func TestCrossReferencesNone(t *testing.T) {
DefinitionKind: xpb.CrossReferencesRequest_ALL_DEFINITIONS,
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
if len(reply.CrossReferences) > 0 || len(reply.Nodes) > 0 {
t.Fatalf("Expected empty CrossReferencesReply; found %v", reply)
@@ -1175,7 +1191,7 @@ func TestCrossReferences(t *testing.T) {
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
Snippets: xpb.SnippetsKind_DEFAULT,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1285,6 +1301,363 @@ func TestCrossReferences(t *testing.T) {
}
}
+type mockPatcher struct {
+ files []*srvpb.FileInfo
+}
+
+func (p *mockPatcher) Close() error { return nil }
+func (p *mockPatcher) AddFile(ctx context.Context, f *srvpb.FileInfo) error {
+ if f != nil {
+ p.files = append(p.files, f)
+ }
+ return nil
+}
+func (p *mockPatcher) patchSpan(span *cpb.Span) {
+ if span == nil {
+ return
+ }
+ // Just move everything over by 1-ish
+ span.Start.ByteOffset++
+ span.Start.LineNumber++
+ span.Start.ColumnOffset++
+ span.End.ByteOffset++
+ span.End.LineNumber++
+ span.End.ColumnOffset++
+}
+func (p *mockPatcher) patchAnchor(a *xpb.Anchor) {
+ p.patchSpan(a.Span)
+ p.patchSpan(a.SnippetSpan)
+}
+
+func (p *mockPatcher) PatchAnchors(ctx context.Context, as []*xpb.Anchor) ([]*xpb.Anchor, error) {
+ for _, a := range as {
+ p.patchAnchor(a)
+ }
+ return as, nil
+}
+func (p *mockPatcher) PatchRelatedAnchors(ctx context.Context, as []*xpb.CrossReferencesReply_RelatedAnchor) ([]*xpb.CrossReferencesReply_RelatedAnchor, error) {
+ for _, a := range as {
+ p.patchAnchor(a.Anchor)
+ for _, site := range a.Site {
+ p.patchAnchor(site)
+ }
+ }
+ return as, nil
+}
+
+func TestDecorationsPatching(t *testing.T) {
+ st := tbl.Construct(t)
+
+ patcher := &mockPatcher{}
+ st.MakePatcher = func(ctx context.Context, ws *xpb.Workspace) (MultiFilePatcher, error) {
+ return patcher, nil
+ }
+
+ reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
+ Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
+ References: true,
+ TargetDefinitions: true,
+
+ Workspace: &xpb.Workspace{Uri: "test:"},
+ PatchAgainstWorkspace: true,
+ })
+ testutil.Fatalf(t, "DecorationsRequest error: %v", err)
+
+ expected := &xpb.DecorationsReply{
+ Location: &xpb.Location{Ticket: "kythe://corpus?path=file/infos"},
+ Revision: "overallFileRev",
+ GeneratedByFile: []*xpb.File{{
+ CorpusPath: &cpb.CorpusPath{
+ Corpus: "corpus",
+ Path: "some/proto.proto",
+ },
+ Revision: "generatedRev",
+ }},
+ Reference: []*xpb.DecorationsReply_Reference{{
+ TargetTicket: "kythe://corpus?path=another/file",
+ Kind: "/kythe/edge/includes/ref",
+ TargetRevision: "anotherFileRev",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 0,
+ LineNumber: 1,
+ ColumnOffset: 0,
+ },
+ End: &cpb.Point{
+ ByteOffset: 4,
+ LineNumber: 1,
+ ColumnOffset: 4,
+ },
+ },
+ }, {
+ TargetTicket: "kythe://corpus?path=def/file#node",
+ TargetDefinition: "kythe://corpus?path=def/file#anchor",
+ Kind: "/kythe/edge/ref",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 5,
+ LineNumber: 1,
+ ColumnOffset: 5,
+ },
+ End: &cpb.Point{
+ ByteOffset: 9,
+ LineNumber: 1,
+ ColumnOffset: 9,
+ },
+ },
+ }},
+ DefinitionLocations: map[string]*xpb.Anchor{
+ "kythe://corpus?path=def/file#anchor": &xpb.Anchor{
+ Ticket: "kythe://corpus?path=def/file#anchor",
+ Parent: "kythe://corpus?path=def/file",
+ Revision: "defFileRev",
+ Span: &cpb.Span{
+ Start: &cpb.Point{ByteOffset: 1, LineNumber: 2, ColumnOffset: 1},
+ End: &cpb.Point{ByteOffset: 5, LineNumber: 2, ColumnOffset: 5},
+ },
+ },
+ },
+ }
+
+ if diff := compare.ProtoDiff(expected, reply); diff != "" {
+ t.Fatalf("Unexpected diff (- expected; + found):\n%s", diff)
+ }
+}
+
+func TestCrossReferencesPatching(t *testing.T) {
+ ticket := "kythe://someCorpus?lang=otpl#signature"
+
+ st := tbl.Construct(t)
+ patcher := &mockPatcher{}
+ st.MakePatcher = func(ctx context.Context, ws *xpb.Workspace) (MultiFilePatcher, error) {
+ return patcher, nil
+ }
+ reply, err := st.CrossReferences(ctx, &xpb.CrossReferencesRequest{
+ Ticket: []string{ticket},
+ DefinitionKind: xpb.CrossReferencesRequest_BINDING_DEFINITIONS,
+ ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
+ Snippets: xpb.SnippetsKind_DEFAULT,
+
+ Workspace: &xpb.Workspace{Uri: "test:"},
+ PatchAgainstWorkspace: true,
+ })
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
+
+ expected := &xpb.CrossReferencesReply_CrossReferenceSet{
+ Ticket: ticket,
+
+ Reference: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
+ Ticket: "kythe:?path=some/utf16/file#0-4",
+ Kind: "/kythe/edge/ref",
+ Parent: "kythe:?path=some/utf16/file",
+
+ Span: &cpb.Span{
+ Start: &cpb.Point{ByteOffset: 1, LineNumber: 2, ColumnOffset: 1},
+ End: &cpb.Point{ByteOffset: 5, LineNumber: 2, ColumnOffset: 5},
+ },
+
+ SnippetSpan: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 1,
+ LineNumber: 2,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 29,
+ LineNumber: 2,
+ ColumnOffset: 29,
+ },
+ },
+ Snippet: "これはいくつかのテキストです",
+ }}, {Anchor: &xpb.Anchor{
+ Ticket: "kythe://c?lang=otpl?path=/a/path#51-55",
+ Kind: "/kythe/edge/ref",
+ Parent: "kythe://c?path=/a/path",
+
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 52,
+ LineNumber: 5,
+ ColumnOffset: 16,
+ },
+ End: &cpb.Point{
+ ByteOffset: 56,
+ LineNumber: 6,
+ ColumnOffset: 3,
+ },
+ },
+
+ SnippetSpan: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 37,
+ LineNumber: 5,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 53,
+ LineNumber: 5,
+ ColumnOffset: 17,
+ },
+ },
+ Snippet: "some random text",
+ }}},
+
+ Definition: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
+ Ticket: "kythe://c?lang=otpl?path=/a/path#27-33",
+ Kind: "/kythe/edge/defines/binding",
+ Parent: "kythe://c?path=/a/path",
+ BuildConfig: "testConfig",
+
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 28,
+ LineNumber: 3,
+ ColumnOffset: 11,
+ },
+ End: &cpb.Point{
+ ByteOffset: 34,
+ LineNumber: 4,
+ ColumnOffset: 6,
+ },
+ },
+
+ SnippetSpan: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 18,
+ LineNumber: 3,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 28,
+ LineNumber: 3,
+ ColumnOffset: 11,
+ },
+ },
+ Snippet: "here and ",
+ }}},
+ }
+ expectedInfos := []*srvpb.FileInfo{}
+
+ xr := reply.CrossReferences[ticket]
+ if xr == nil {
+ t.Fatalf("Missing expected CrossReferences; found: %#v", reply)
+ }
+ sort.Sort(byOffset(xr.Reference))
+
+ if err := testutil.DeepEqual(expected, xr); err != nil {
+ t.Fatal(err)
+ }
+ if err := testutil.DeepEqual(expectedInfos, patcher.files); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestCrossReferencesFiltering(t *testing.T) {
+ ticket := "kythe://someCorpus?lang=otpl#signature"
+
+ st := tbl.Construct(t)
+ reply, err := st.CrossReferences(ctx, &xpb.CrossReferencesRequest{
+ Ticket: []string{ticket},
+ DefinitionKind: xpb.CrossReferencesRequest_BINDING_DEFINITIONS,
+ ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
+ Snippets: xpb.SnippetsKind_DEFAULT,
+
+ CorpusPathFilters: mustParseFilters(`
+filter: {
+ type: INCLUDE_ONLY
+ corpus: "^c$"
+}
+ `),
+ })
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
+
+ expected := &xpb.CrossReferencesReply_CrossReferenceSet{
+ Ticket: ticket,
+
+ Reference: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
+ Ticket: "kythe://c?lang=otpl?path=/a/path#51-55",
+ Kind: "/kythe/edge/ref",
+ Parent: "kythe://c?path=/a/path",
+
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 51,
+ LineNumber: 4,
+ ColumnOffset: 15,
+ },
+ End: &cpb.Point{
+ ByteOffset: 55,
+ LineNumber: 5,
+ ColumnOffset: 2,
+ },
+ },
+
+ SnippetSpan: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 36,
+ LineNumber: 4,
+ },
+ End: &cpb.Point{
+ ByteOffset: 52,
+ LineNumber: 4,
+ ColumnOffset: 16,
+ },
+ },
+ Snippet: "some random text",
+ }}},
+
+ Definition: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
+ Ticket: "kythe://c?lang=otpl?path=/a/path#27-33",
+ Kind: "/kythe/edge/defines/binding",
+ Parent: "kythe://c?path=/a/path",
+ BuildConfig: "testConfig",
+
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 27,
+ LineNumber: 2,
+ ColumnOffset: 10,
+ },
+ End: &cpb.Point{
+ ByteOffset: 33,
+ LineNumber: 3,
+ ColumnOffset: 5,
+ },
+ },
+
+ SnippetSpan: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 17,
+ LineNumber: 2,
+ },
+ End: &cpb.Point{
+ ByteOffset: 27,
+ LineNumber: 2,
+ ColumnOffset: 10,
+ },
+ },
+ Snippet: "here and ",
+ }}},
+ }
+
+ if err := testutil.DeepEqual(&xpb.CrossReferencesReply_Total{
+ Definitions: 1,
+ References: 1,
+ }, reply.Total); err != nil {
+ t.Error(err)
+ }
+
+ xr := reply.CrossReferences[ticket]
+ if xr == nil {
+ t.Fatalf("Missing expected CrossReferences; found: %s", reply)
+ }
+ sort.Sort(byOffset(xr.Reference))
+
+ if diff := compare.ProtoDiff(expected, xr); diff != "" {
+ t.Fatalf("(-expected; +found):\n%s", diff)
+ }
+}
+
func TestCrossReferences_BuildConfigRefs(t *testing.T) {
ticket := "kythe://someCorpus?lang=otpl#signature"
@@ -1296,7 +1669,7 @@ func TestCrossReferences_BuildConfigRefs(t *testing.T) {
Snippets: xpb.SnippetsKind_DEFAULT,
BuildConfig: []string{"testConfig"},
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1360,7 +1733,7 @@ func TestCrossReferencesRelatedNodes(t *testing.T) {
Ticket: []string{ticket},
Filter: []string{"**"},
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1415,7 +1788,7 @@ func TestCrossReferencesMarkedSource(t *testing.T) {
Ticket: []string{ticket},
Filter: []string{"**"},
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1464,7 +1837,7 @@ func TestCrossReferencesMerge(t *testing.T) {
CallerKind: xpb.CrossReferencesRequest_DIRECT_CALLERS,
Filter: []string{"**"},
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1532,7 +1905,7 @@ func TestCrossReferencesIndirection(t *testing.T) {
Ticket: []string{ticket},
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1572,7 +1945,7 @@ func TestCrossReferencesIndirection(t *testing.T) {
Ticket: []string{ticket},
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1641,7 +2014,7 @@ func TestCrossReferencesIndirection(t *testing.T) {
Ticket: []string{ticket},
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1710,7 +2083,7 @@ func TestCrossReferencesIndirection(t *testing.T) {
Ticket: []string{ticket},
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1762,7 +2135,7 @@ func TestCrossReferencesIndirection(t *testing.T) {
Ticket: []string{ticket},
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1840,7 +2213,7 @@ func TestCrossReferencesDirectCallers(t *testing.T) {
Ticket: []string{ticket},
CallerKind: xpb.CrossReferencesRequest_DIRECT_CALLERS,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1885,7 +2258,7 @@ func TestCrossReferencesOverrideCallers(t *testing.T) {
Ticket: []string{ticket},
CallerKind: xpb.CrossReferencesRequest_OVERRIDE_CALLERS,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply_CrossReferenceSet{
Ticket: ticket,
@@ -1953,7 +2326,7 @@ func TestCrossReferencesRevisions(t *testing.T) {
ReferenceKind: xpb.CrossReferencesRequest_ALL_REFERENCES,
Snippets: xpb.SnippetsKind_NONE,
})
- testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)
+ testutil.Fatalf(t, "CrossReferencesRequest error: %v", err)
expected := &xpb.CrossReferencesReply{
Total: &xpb.CrossReferencesReply_Total{
@@ -2042,6 +2415,18 @@ func TestDocumentation(t *testing.T) {
"kythe:?path=def/location#defDoc": &xpb.Anchor{
Ticket: "kythe:?path=def/location#defDoc",
Parent: "kythe:?path=def/location",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 1,
+ LineNumber: 1,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 4,
+ LineNumber: 1,
+ ColumnOffset: 4,
+ },
+ },
},
},
}
@@ -2093,6 +2478,90 @@ func TestDocumentationChildren(t *testing.T) {
"kythe:?path=def/location#defDoc": &xpb.Anchor{
Ticket: "kythe:?path=def/location#defDoc",
Parent: "kythe:?path=def/location",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 1,
+ LineNumber: 1,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 4,
+ LineNumber: 1,
+ ColumnOffset: 4,
+ },
+ },
+ },
+ },
+ }
+
+ if reply == nil || err != nil {
+ t.Fatalf("Documentation call failed: (reply: %v; error: %v)", reply, err)
+ } else if diff := compare.ProtoDiff(expected, reply); diff != "" {
+ t.Fatalf("(-expected; +found):\n%s", diff)
+ }
+}
+
+func TestDocumentationPatching(t *testing.T) {
+ st := tbl.Construct(t)
+
+ patcher := &mockPatcher{}
+ st.MakePatcher = func(ctx context.Context, ws *xpb.Workspace) (MultiFilePatcher, error) {
+ return patcher, nil
+ }
+
+ reply, err := st.Documentation(ctx, &xpb.DocumentationRequest{
+ Ticket: []string{"kythe:#documented"},
+
+ IncludeChildren: true,
+
+ Workspace: &xpb.Workspace{Uri: "test:"},
+ PatchAgainstWorkspace: true,
+ })
+
+ expected := &xpb.DocumentationReply{
+ Document: []*xpb.DocumentationReply_Document{{
+ Ticket: "kythe:#documented",
+ Text: &xpb.Printable{
+ RawText: "some documentation text",
+ },
+ MarkedSource: &cpb.MarkedSource{
+ Kind: cpb.MarkedSource_IDENTIFIER,
+ PreText: "DocumentBuilderFactory",
+ },
+ Children: []*xpb.DocumentationReply_Document{{
+ Ticket: "kythe:#childDoc",
+ Text: &xpb.Printable{
+ RawText: "child document text",
+ },
+ }, {
+ Ticket: "kythe:#childDocBy",
+ Text: &xpb.Printable{
+ RawText: "second child document text",
+ },
+ }},
+ }},
+ Nodes: nodeInfos(getNodes(
+ "kythe:#childDoc",
+ "kythe:#childDocBy",
+ "kythe:#documented",
+ "kythe:#secondChildDoc",
+ )),
+ DefinitionLocations: map[string]*xpb.Anchor{
+ "kythe:?path=def/location#defDoc": &xpb.Anchor{
+ Ticket: "kythe:?path=def/location#defDoc",
+ Parent: "kythe:?path=def/location",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 2,
+ LineNumber: 2,
+ ColumnOffset: 2,
+ },
+ End: &cpb.Point{
+ ByteOffset: 5,
+ LineNumber: 2,
+ ColumnOffset: 5,
+ },
+ },
},
},
}
@@ -2126,6 +2595,18 @@ func TestDocumentationIndirection(t *testing.T) {
"kythe:?path=def/location#defDoc": &xpb.Anchor{
Ticket: "kythe:?path=def/location#defDoc",
Parent: "kythe:?path=def/location",
+ Span: &cpb.Span{
+ Start: &cpb.Point{
+ ByteOffset: 1,
+ LineNumber: 1,
+ ColumnOffset: 1,
+ },
+ End: &cpb.Point{
+ ByteOffset: 4,
+ LineNumber: 1,
+ ColumnOffset: 4,
+ },
+ },
},
},
}
@@ -2137,6 +2618,64 @@ func TestDocumentationIndirection(t *testing.T) {
}
}
+func TestCorpusPathFilters(t *testing.T) {
+ tests := []struct {
+ filters *xpb.CorpusPathFilters
+
+ includes, excludes []string
+ }{
+ {mustParseFilters(`filter: { type: INCLUDE_ONLY corpus: "^kythe3" }`),
+ []string{cps("kythe3", "", ""), cps("kythe3//branch", "", "")},
+ []string{cps("other", "", ""), cps("other", "kythe3", "kythe3")}},
+ {mustParseFilters(`filter: { type: EXCLUDE root: ".+" }`),
+ []string{cps("kythe3", "", ""), cps("kythe3//branch", "", ""), cps("oss", "", "any/path")},
+ []string{cps("kythe3", "genfiles", ""), cps("other", "bin", "some/path")}},
+ {mustParseFilters(`filter: { type: INCLUDE_ONLY corpus: "^kythe3" root: "genfiles" }`),
+ []string{cps("kythe3", "genfiles", ""), cps("kythe3//branch", "genfiles", "")},
+ []string{cps("kythe2", "genfiles", ""), cps("kythe3", "bin", "path"), cps("other", "bin", "some/path")}},
+ {mustParseFilters(`filter: { type: INCLUDE_ONLY corpus: "kythe" } filter: { type: INCLUDE_ONLY corpus: "2|3" }`),
+ []string{cps("kythe3", "genfiles", "path"), cps("kythe2", "", "blah")},
+ []string{cps("kythe4", "", ""), cps("kythe", "kythe2", "kythe3")}},
+ {mustParseFilters(`filter: { type: EXCLUDE root: ".+" } filter: { type: INCLUDE_ONLY corpus: "^kythe3"}`),
+ []string{cps("kythe3", "", "any/path"), cps("kythe3//branch", "", "some/path")},
+ []string{cps("kythe3", "genfiles", "any/path"), cps("kythe3//branch", "bin", "some/path")}},
+ {mustParseFilters(`filter: { type: INCLUDE_ONLY resolved_path: "^kythe3/branch/genfiles/"}`),
+ []string{cps("kythe3//branch", "genfiles", "any/path"), cps("kythe3//branch", "genfiles/more", "any/path")},
+ []string{cps("kythe3", "bin", "any/path"), cps("kythe3", "genfiles", "some/path")}},
+ }
+
+ for i, test := range tests {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ f, err := compileCorpusPathFilters(test.filters, nil)
+ testutil.Fatalf(t, "Error: %v", err)
+
+ for _, include := range test.includes {
+ if !f.AllowTicket(include) {
+ t.Errorf("Expected %q to be included but it wasn't", include)
+ }
+ }
+ for _, exclude := range test.excludes {
+ if f.AllowTicket(exclude) {
+ t.Errorf("Expected %q to be excluded but it wasn't", exclude)
+ }
+ }
+ })
+ }
+}
+
+func cps(corpus, root, path string) string {
+ u := &kytheuri.URI{Corpus: corpus, Root: root, Path: path}
+ return u.String()
+}
+
+func mustParseFilters(msg string) *xpb.CorpusPathFilters {
+ var f xpb.CorpusPathFilters
+ if err := prototext.Unmarshal([]byte(msg), &f); err != nil {
+ panic(err)
+ }
+ return &f
+}
+
// byOffset implements the sort.Interface for *xpb.CrossReferencesReply_RelatedAnchors.
type byOffset []*xpb.CrossReferencesReply_RelatedAnchor
@@ -2196,16 +2735,16 @@ type testTable struct {
func (tbl *testTable) Construct(t *testing.T) *Table {
p := make(testProtoTable)
for _, d := range tbl.Decorations {
- testutil.FatalOnErrT(t, "Error writing file decorations: %v", p.Put(ctx, DecorationsKey(mustFix(t, d.File.Ticket)), d))
+ testutil.Fatalf(t, "Error writing file decorations: %v", p.Put(ctx, DecorationsKey(mustFix(t, d.File.Ticket)), d))
}
for _, cr := range tbl.RefSets {
- testutil.FatalOnErrT(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesKey(mustFix(t, cr.SourceTicket)), cr))
+ testutil.Fatalf(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesKey(mustFix(t, cr.SourceTicket)), cr))
}
for _, crp := range tbl.RefPages {
- testutil.FatalOnErrT(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesPageKey(crp.PageKey), crp))
+ testutil.Fatalf(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesPageKey(crp.PageKey), crp))
}
for _, doc := range tbl.Documents {
- testutil.FatalOnErrT(t, "Error writing documents: %v", p.Put(ctx, DocumentationKey(doc.Ticket), doc))
+ testutil.Fatalf(t, "Error writing documents: %v", p.Put(ctx, DocumentationKey(doc.Ticket), doc))
}
return NewCombinedTable(p)
}