fork of https://github.com/sourcegraph/zoekt
1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package query
16
17import (
18 "log"
19 "reflect"
20 "regexp/syntax"
21 "testing"
22
23 "github.com/grafana/regexp"
24)
25
26var _ = log.Println
27
28func TestQueryString(t *testing.T) {
29 q := &Or{[]Q{
30 &And{[]Q{
31 &Substring{Pattern: "hoi"},
32 &Not{&Substring{Pattern: "hai"}},
33 }},
34 }}
35 got := q.String()
36 want := `(or (and substr:"hoi" (not substr:"hai")))`
37
38 if got != want {
39 t.Errorf("got %s, want %s", got, want)
40 }
41}
42
43func TestSimplify(t *testing.T) {
44 type testcase struct {
45 in Q
46 want Q
47 }
48
49 cases := []testcase{
50 {
51 in: NewOr(
52 NewOr(
53 NewAnd(&Substring{Pattern: "hoi"},
54 &Not{&Substring{Pattern: "hai"}}),
55 NewOr(
56 &Substring{Pattern: "zip"},
57 &Substring{Pattern: "zap"},
58 ))),
59 want: NewOr(
60 NewAnd(
61 &Substring{Pattern: "hoi"},
62 &Not{&Substring{Pattern: "hai"}}),
63 &Substring{Pattern: "zip"},
64 &Substring{Pattern: "zap"}),
65 },
66 {in: &And{}, want: &Const{true}},
67 {in: &Or{}, want: &Const{false}},
68 {in: NewAnd(&Const{true}, &Const{false}), want: &Const{false}},
69 {in: NewOr(&Const{false}, &Const{true}), want: &Const{true}},
70 {in: &Not{&Const{true}}, want: &Const{false}},
71 {
72 in: NewAnd(
73 &Substring{Pattern: "byte"},
74 &Not{NewAnd(&Substring{Pattern: "byte"})}),
75 want: NewAnd(
76 &Substring{Pattern: "byte"},
77 &Not{&Substring{Pattern: "byte"}}),
78 },
79 {
80 in: NewAnd(
81 NewSingleBranchesRepos("HEAD"), // Empty list matches nothing
82 &Not{&Type{Type: TypeRepo, Child: &Substring{Pattern: "hi"}}}),
83 want: &Const{false},
84 },
85 {
86 in: NewAnd(
87 NewSingleBranchesRepos("HEAD", 1),
88 &Not{&Type{Type: TypeRepo, Child: &Substring{Pattern: "hi"}}}),
89 want: NewAnd(
90 NewSingleBranchesRepos("HEAD", 1),
91 &Not{&Type{Type: TypeRepo, Child: &Substring{Pattern: "hi"}}}),
92 },
93 }
94
95 for _, c := range cases {
96 got := Simplify(c.in)
97 if !reflect.DeepEqual(got, c.want) {
98 t.Errorf("got %s, want %s", got, c.want)
99 }
100 }
101}
102
103func TestMap(t *testing.T) {
104 in := NewAnd(&Substring{Pattern: "bla"}, &Not{&Repo{Regexp: regexp.MustCompile("foo")}})
105 out := NewAnd(&Substring{Pattern: "bla"}, &Not{&Const{false}})
106
107 f := func(q Q) Q {
108 if _, ok := q.(*Repo); ok {
109 return &Const{false}
110 }
111 return q
112 }
113 got := Map(in, f)
114 if !reflect.DeepEqual(got, out) {
115 t.Errorf("got %v, want %v", got, out)
116 }
117}
118
119func TestVisitAtoms(t *testing.T) {
120 in := NewAnd(&Substring{}, &Repo{}, &Not{&Const{}})
121 count := 0
122 VisitAtoms(in, func(q Q) {
123 count++
124 })
125 if count != 3 {
126 t.Errorf("got %d, want 3", count)
127 }
128}
129
130func TestExpandFileContent(t *testing.T) {
131 re, _ := syntax.Parse("foo", syntax.Perl)
132
133 cases := []struct {
134 q Q
135 want string
136 }{
137 {
138 q: &Substring{FileName: true, Content: true},
139 want: "(or file_substr:\"\" content_substr:\"\")",
140 },
141 {
142 q: &Substring{FileName: false, Content: false},
143 want: "(or file_substr:\"\" content_substr:\"\")",
144 },
145
146 {
147 q: &Substring{FileName: true, Content: false},
148 want: "file_substr:\"\"",
149 },
150 {
151 q: &Substring{FileName: false, Content: true},
152 want: "content_substr:\"\"",
153 },
154 {
155 q: &Regexp{Regexp: re, FileName: true, Content: true},
156 want: "(or file_regex:\"foo\" regex:\"foo\")",
157 },
158 {
159 q: &Regexp{Regexp: re, FileName: false, Content: false},
160 want: "(or file_regex:\"foo\" regex:\"foo\")",
161 },
162
163 {
164 q: &Regexp{Regexp: re, FileName: true, Content: false},
165 want: "file_regex:\"foo\"",
166 },
167 {
168 q: &Regexp{Regexp: re, FileName: false, Content: true},
169 want: "regex:\"foo\"",
170 },
171 }
172
173 for _, tt := range cases {
174 t.Run("", func(t *testing.T) {
175 if got := ExpandFileContent(tt.q); got.String() != tt.want {
176 t.Fatalf("got %s, want %s\n", got.String(), tt.want)
177 }
178 })
179 }
180}