fork of https://github.com/sourcegraph/zoekt
1package search
2
3import (
4 "context"
5 "fmt"
6 "testing"
7
8 "github.com/sourcegraph/zoekt"
9 "github.com/sourcegraph/zoekt/index"
10 "github.com/sourcegraph/zoekt/query"
11)
12
13func TestSearchTypeRepo(t *testing.T) {
14 ss := newShardedSearcher(2)
15 nextShardNum := 1
16 addShard := func(docs ...index.Document) {
17 b := testShardBuilder(t, &zoekt.Repository{ID: 1, Name: "reponame"}, docs...)
18 shard := searcherForTest(t, b)
19 ss.replace(map[string]zoekt.Searcher{fmt.Sprintf("key-%d", nextShardNum): shard})
20 nextShardNum++
21 }
22 addShard(
23 index.Document{Name: "f1", Content: []byte("bla the needle")},
24 index.Document{Name: "f2", Content: []byte("another file another needle")})
25 addShard(
26 index.Document{Name: "f3", Content: []byte("another shard")})
27
28 searcher := &typeRepoSearcher{ss}
29 search := func(q query.Q, o ...zoekt.SearchOptions) *zoekt.SearchResult {
30 t.Helper()
31 var opts zoekt.SearchOptions
32 if len(o) > 0 {
33 opts = o[0]
34 }
35 res, err := searcher.Search(context.Background(), q, &opts)
36 if err != nil {
37 t.Fatalf("Search(%s): %v", q, err)
38 }
39 return res
40 }
41 wantSingleMatch := func(res *zoekt.SearchResult, want string) {
42 t.Helper()
43 fmatches := res.Files
44 if len(fmatches) != 1 || len(fmatches[0].LineMatches) != 1 {
45 t.Fatalf("got %v, want 1 matches", fmatches)
46 }
47 got := fmt.Sprintf("%s:%d", fmatches[0].FileName, fmatches[0].LineMatches[0].LineFragments[0].Offset)
48 if got != want {
49 t.Errorf("1: got %s, want %s", got, want)
50 }
51 }
52
53 // type filter matches in different file
54 res := search(query.NewAnd(
55 &query.Type{
56 Type: query.TypeRepo,
57 Child: &query.Substring{Pattern: "bla"},
58 },
59 &query.Substring{Pattern: "file"}))
60 wantSingleMatch(res, "f2:8")
61
62 // type filter matches in same file. Do not include that result
63 res = search(query.NewAnd(
64 &query.Type{
65 Type: query.TypeRepo,
66 Child: &query.Substring{Pattern: "needle"},
67 },
68 &query.Substring{Pattern: "file"}))
69 wantSingleMatch(res, "f2:8")
70
71 // type filter matches path in different file
72 res = search(query.NewAnd(
73 &query.Type{
74 Type: query.TypeRepo,
75 Child: &query.Substring{Pattern: "f1", FileName: true},
76 },
77 &query.Substring{Pattern: "file"}))
78 wantSingleMatch(res, "f2:8")
79
80 // type filter matches path in same file
81 res = search(query.NewAnd(
82 &query.Type{
83 Type: query.TypeRepo,
84 Child: &query.Substring{Pattern: "f2", FileName: true},
85 },
86 &query.Substring{Pattern: "file"}))
87 wantSingleMatch(res, "f2:8")
88
89 // no match by content
90 res = search(query.NewAnd(
91 &query.Type{
92 Type: query.TypeRepo,
93 Child: &query.Substring{Pattern: "nope"},
94 },
95 &query.Substring{Pattern: "file"}))
96 if len(res.Files) != 0 {
97 t.Fatalf("got %v, want 0 matches", len(res.Files))
98 }
99
100 // no index by path
101 res = search(query.NewAnd(
102 &query.Type{
103 Type: query.TypeRepo,
104 Child: &query.Substring{Pattern: "nope", FileName: true},
105 },
106 &query.Substring{Pattern: "file"}))
107 if len(res.Files) != 0 {
108 t.Fatalf("got %v, want 0 matches", len(res.Files))
109 }
110
111 // type filter matches in a different shard
112 res = search(query.NewAnd(
113 &query.Type{
114 Type: query.TypeRepo,
115 Child: &query.Substring{Pattern: "another shard"},
116 },
117 &query.Substring{Pattern: "file"}))
118 wantSingleMatch(res, "f2:8")
119}