omegatest: Fix shell printf quoting issues
[xapian.git] / xapian-applications / omega / omegatest
blobafc5ba70429a08c53cd3958f1dff40e9ac1839d8
1 #!/bin/sh
2 # omegatest: Test omega CGI
4 # Copyright (C) 2015,2016,2017,2018 Olly Betts
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; either version 2 of the
9 # License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 # USA
20 set -e
22 : ${OMEGA=./omega}
23 : ${SCRIPTINDEX=./scriptindex}
25 # Suppress HTTP Content-Type header.
26 SERVER_PROTOCOL=INCLUDED
27 export SERVER_PROTOCOL
29 # Set up an empty database.
30 TEST_DB=test-db
31 rm -rf "$TEST_DB"
32 echo 'inmemory' > "$TEST_DB"
34 # Simple template which just shows the parsed query.
35 TEST_TEMPLATE=test-template
36 printf '$querydescription' > "$TEST_TEMPLATE"
38 TEST_INDEXSCRIPT=test-indexscript
40 OMEGA_CONFIG_FILE=test-omega.conf
41 export OMEGA_CONFIG_FILE
42 cat > "$OMEGA_CONFIG_FILE" <<__END__
43 database_dir .
44 template_dir .
45 log_dir tmplog
46 default_template $TEST_TEMPLATE
47 default_db $TEST_DB
48 __END__
50 failed=0
52 testcase() {
53 expected=$1
54 shift
55 # If there are no positional parameters, pass one as otherwise omega will
56 # wait for parameters on stdin.
57 [ "$#" != 0 ] || { set x dummy; shift; }
58 output=`$FAKETIME ${FAKE_NOW+"$FAKE_NOW"} "$OMEGA" "$@"`
59 if [ "$output" != "$expected" ] ; then
60 echo "$OMEGA $@:"
61 printf '%s\n' " expected: «${expected}»"
62 printf '%s\n' " received: «${output}»"
63 failed=`expr $failed + 1`
67 qtestcase() {
68 expected="Query($1)"
69 shift
70 testcase "$expected" "$@"
73 FAKETIME=
74 unset FAKE_NOW
76 # Test a few simple things.
77 qtestcase 'Zsimpl@1' P=simple
78 qtestcase '(chocolate@1 FILTER Tconfectionary/fudge)' P=Chocolate B=Tconfectionary/fudge
80 # Test date value ranges.
81 qtestcase 'VALUE_RANGE 0 2 ~' DATEVALUE=0 START=2000
82 qtestcase 'VALUE_RANGE 0 2 ~' DATEVALUE=0 START=200001
83 qtestcase 'VALUE_RANGE 0 2 ~' DATEVALUE=0 START=20000101
84 qtestcase 'VALUE_LE 1 1~' DATEVALUE=1 END=1999
85 qtestcase 'VALUE_LE 1 1~' DATEVALUE=1 END=199912
86 qtestcase 'VALUE_LE 1 1~' DATEVALUE=1 END=19991231
87 qtestcase 'VALUE_RANGE 2 201 ~' DATEVALUE=2 START=2010
88 qtestcase 'VALUE_RANGE 2 201 ~' DATEVALUE=2 START=201001
89 qtestcase 'VALUE_RANGE 2 201 ~' DATEVALUE=2 START=20100101
90 qtestcase 'VALUE_LE 3 198~' DATEVALUE=3 END=1989
91 qtestcase 'VALUE_LE 3 198~' DATEVALUE=3 END=198912
92 qtestcase 'VALUE_LE 3 198~' DATEVALUE=3 END=19891231
93 qtestcase 'VALUE_RANGE 4 1974 ~' DATEVALUE=4 START=1974
94 qtestcase 'VALUE_RANGE 4 1974 ~' DATEVALUE=4 START=197401
95 qtestcase 'VALUE_RANGE 4 1974 ~' DATEVALUE=4 START=19740101
96 qtestcase 'VALUE_LE 5 1974~' DATEVALUE=5 END=1974
97 qtestcase 'VALUE_LE 5 1974~' DATEVALUE=5 END=197412
98 qtestcase 'VALUE_LE 5 1974~' DATEVALUE=5 END=19741231
99 qtestcase 'VALUE_RANGE 6 20151 ~' DATEVALUE=6 START=201510
100 qtestcase 'VALUE_RANGE 6 20151 ~' DATEVALUE=6 START=20151001
101 qtestcase 'VALUE_LE 7 19870~' DATEVALUE=7 END=198709
102 qtestcase 'VALUE_LE 7 19870~' DATEVALUE=7 END=19870930
103 qtestcase 'VALUE_RANGE 8 201512 ~' DATEVALUE=8 START=201512
104 qtestcase 'VALUE_RANGE 8 201512 ~' DATEVALUE=8 START=20151201
105 qtestcase 'VALUE_LE 9 201511~' DATEVALUE=9 END=201511
106 qtestcase 'VALUE_LE 9 201511~' DATEVALUE=9 END=20151130
107 qtestcase 'VALUE_RANGE 10 2015021 ~' DATEVALUE=10 START=20150210
108 qtestcase 'VALUE_RANGE 10 2000022 ~' DATEVALUE=10 START=20000220
109 qtestcase 'VALUE_LE 11 19840401~' DATEVALUE=11 END=19840401
110 qtestcase 'VALUE_LE 11 19881128~' DATEVALUE=11 END=19881128
112 # Leap year tests:
113 qtestcase 'VALUE_LE 1 201502~' DATEVALUE=1 END=20150228
114 qtestcase 'VALUE_LE 1 198802~' DATEVALUE=1 END=19880229
115 qtestcase 'VALUE_LE 1 19880228~' DATEVALUE=1 END=19880228
116 qtestcase 'VALUE_LE 1 200002~' DATEVALUE=1 END=20000229
117 qtestcase 'VALUE_LE 1 20000228~' DATEVALUE=1 END=20000228
118 # FIXME: These two currently require 64-bit time_t:
119 #qtestcase 'VALUE_LE 1 190002~' DATEVALUE=1 END=19000228
120 #qtestcase 'VALUE_LE 1 210002~' DATEVALUE=1 END=21000228
122 # Month starts and ends:
123 qtestcase 'VALUE_RANGE 0 2015 201501~' DATEVALUE=0 START=20150101 END=20150131
124 qtestcase 'VALUE_RANGE 0 2015 20150130~' DATEVALUE=0 START=20150101 END=20150130
125 qtestcase 'VALUE_RANGE 0 201502 201502~' DATEVALUE=0 START=20150201 END=20150228
126 qtestcase 'VALUE_RANGE 0 201502 20150227~' DATEVALUE=0 START=20150201 END=20150227
127 qtestcase 'VALUE_RANGE 0 201503 201503~' DATEVALUE=0 START=20150301 END=20150331
128 qtestcase 'VALUE_RANGE 0 201503 20150330~' DATEVALUE=0 START=20150301 END=20150330
129 qtestcase 'VALUE_RANGE 0 201504 201504~' DATEVALUE=0 START=20150401 END=20150430
130 qtestcase 'VALUE_RANGE 0 201504 2015042~' DATEVALUE=0 START=20150401 END=20150429
131 qtestcase 'VALUE_RANGE 0 201505 201505~' DATEVALUE=0 START=20150501 END=20150531
132 qtestcase 'VALUE_RANGE 0 201505 20150530~' DATEVALUE=0 START=20150501 END=20150530
133 qtestcase 'VALUE_RANGE 0 201506 201506~' DATEVALUE=0 START=20150601 END=20150630
134 qtestcase 'VALUE_RANGE 0 201506 2015062~' DATEVALUE=0 START=20150601 END=20150629
135 qtestcase 'VALUE_RANGE 0 201507 201507~' DATEVALUE=0 START=20150701 END=20150731
136 qtestcase 'VALUE_RANGE 0 201507 20150730~' DATEVALUE=0 START=20150701 END=20150730
137 qtestcase 'VALUE_RANGE 0 201508 201508~' DATEVALUE=0 START=20150801 END=20150831
138 qtestcase 'VALUE_RANGE 0 201508 20150830~' DATEVALUE=0 START=20150801 END=20150830
139 qtestcase 'VALUE_RANGE 0 201509 20150~' DATEVALUE=0 START=20150901 END=20150930
140 qtestcase 'VALUE_RANGE 0 201509 2015092~' DATEVALUE=0 START=20150901 END=20150929
141 qtestcase 'VALUE_RANGE 0 20151 201510~' DATEVALUE=0 START=20151001 END=20151031
142 qtestcase 'VALUE_RANGE 0 20151 20151030~' DATEVALUE=0 START=20151001 END=20151030
143 qtestcase 'VALUE_RANGE 0 201511 201511~' DATEVALUE=0 START=20151101 END=20151130
144 qtestcase 'VALUE_RANGE 0 201511 2015112~' DATEVALUE=0 START=20151101 END=20151129
145 qtestcase 'VALUE_RANGE 0 201512 2015~' DATEVALUE=0 START=20151201 END=20151231
146 qtestcase 'VALUE_RANGE 0 201512 20151230~' DATEVALUE=0 START=20151201 END=20151230
148 # Forward spans:
149 qtestcase 'VALUE_RANGE 0 20151104 20151106~' DATEVALUE=0 START=20151104 SPAN=3
150 qtestcase 'VALUE_RANGE 0 20141104 20151103~' DATEVALUE=0 START=20141104 SPAN=365
152 # Backward spans:
153 qtestcase 'VALUE_RANGE 0 20151104 20151106~' DATEVALUE=0 END=20151106 SPAN=3
154 qtestcase 'VALUE_RANGE 0 20141104 20151103~' DATEVALUE=0 END=20151103 SPAN=365
156 # Check that if START, END and SPAN are all passed, START is ignored:
157 qtestcase 'VALUE_RANGE 0 20151104 20151106~' DATEVALUE=0 START=19700101 END=20151106 SPAN=3
159 # Test date value ranges using newer ".SLOT" parameters.
160 qtestcase 'VALUE_RANGE 0 2 ~' START.0=2000
161 qtestcase 'VALUE_RANGE 0 2 ~' START.0=200001
162 qtestcase 'VALUE_RANGE 0 2 ~' START.0=20000101
163 qtestcase 'VALUE_LE 1 1~' END.1=1999
164 qtestcase 'VALUE_LE 1 1~' END.1=199912
165 qtestcase 'VALUE_LE 1 1~' END.1=19991231
166 qtestcase 'VALUE_RANGE 2 201 ~' START.2=2010
167 qtestcase 'VALUE_RANGE 2 201 ~' START.2=201001
168 qtestcase 'VALUE_RANGE 2 201 ~' START.2=20100101
169 qtestcase 'VALUE_LE 3 198~' END.3=1989
170 qtestcase 'VALUE_LE 3 198~' END.3=198912
171 qtestcase 'VALUE_LE 3 198~' END.3=19891231
172 qtestcase 'VALUE_RANGE 4 1974 ~' START.4=1974
173 qtestcase 'VALUE_RANGE 4 1974 ~' START.4=197401
174 qtestcase 'VALUE_RANGE 4 1974 ~' START.4=19740101
175 qtestcase 'VALUE_LE 5 1974~' END.5=1974
176 qtestcase 'VALUE_LE 5 1974~' END.5=197412
177 qtestcase 'VALUE_LE 5 1974~' END.5=19741231
178 qtestcase 'VALUE_RANGE 6 20151 ~' START.6=201510
179 qtestcase 'VALUE_RANGE 6 20151 ~' START.6=20151001
180 qtestcase 'VALUE_LE 7 19870~' END.7=198709
181 qtestcase 'VALUE_LE 7 19870~' END.7=19870930
182 qtestcase 'VALUE_RANGE 8 201512 ~' START.8=201512
183 qtestcase 'VALUE_RANGE 8 201512 ~' START.8=20151201
184 qtestcase 'VALUE_LE 9 201511~' END.9=201511
185 qtestcase 'VALUE_LE 9 201511~' END.9=20151130
186 qtestcase 'VALUE_RANGE 10 2015021 ~' START.10=20150210
187 qtestcase 'VALUE_RANGE 10 2000022 ~' START.10=20000220
188 qtestcase 'VALUE_LE 11 19840401~' END.11=19840401
189 qtestcase 'VALUE_LE 11 19881128~' END.11=19881128
191 # Leap year tests:
192 qtestcase 'VALUE_LE 1 201502~' END.1=20150228
193 qtestcase 'VALUE_LE 1 198802~' END.1=19880229
194 qtestcase 'VALUE_LE 1 19880228~' END.1=19880228
195 qtestcase 'VALUE_LE 1 200002~' END.1=20000229
196 qtestcase 'VALUE_LE 1 20000228~' END.1=20000228
197 # FIXME: These two currently require 64-bit time_t:
198 #qtestcase 'VALUE_LE 1 190002~' END.1=19000228
199 #qtestcase 'VALUE_LE 1 210002~' END.1=21000228
201 # Month starts and ends:
202 qtestcase 'VALUE_RANGE 0 2015 201501~' START.0=20150101 END.0=20150131
203 qtestcase 'VALUE_RANGE 0 2015 20150130~' START.0=20150101 END.0=20150130
204 qtestcase 'VALUE_RANGE 0 201502 201502~' START.0=20150201 END.0=20150228
205 qtestcase 'VALUE_RANGE 0 201502 20150227~' START.0=20150201 END.0=20150227
206 qtestcase 'VALUE_RANGE 0 201503 201503~' START.0=20150301 END.0=20150331
207 qtestcase 'VALUE_RANGE 0 201503 20150330~' START.0=20150301 END.0=20150330
208 qtestcase 'VALUE_RANGE 0 201504 201504~' START.0=20150401 END.0=20150430
209 qtestcase 'VALUE_RANGE 0 201504 2015042~' START.0=20150401 END.0=20150429
210 qtestcase 'VALUE_RANGE 0 201505 201505~' START.0=20150501 END.0=20150531
211 qtestcase 'VALUE_RANGE 0 201505 20150530~' START.0=20150501 END.0=20150530
212 qtestcase 'VALUE_RANGE 0 201506 201506~' START.0=20150601 END.0=20150630
213 qtestcase 'VALUE_RANGE 0 201506 2015062~' START.0=20150601 END.0=20150629
214 qtestcase 'VALUE_RANGE 0 201507 201507~' START.0=20150701 END.0=20150731
215 qtestcase 'VALUE_RANGE 0 201507 20150730~' START.0=20150701 END.0=20150730
216 qtestcase 'VALUE_RANGE 0 201508 201508~' START.0=20150801 END.0=20150831
217 qtestcase 'VALUE_RANGE 0 201508 20150830~' START.0=20150801 END.0=20150830
218 qtestcase 'VALUE_RANGE 0 201509 20150~' START.0=20150901 END.0=20150930
219 qtestcase 'VALUE_RANGE 0 201509 2015092~' START.0=20150901 END.0=20150929
220 qtestcase 'VALUE_RANGE 0 20151 201510~' START.0=20151001 END.0=20151031
221 qtestcase 'VALUE_RANGE 0 20151 20151030~' START.0=20151001 END.0=20151030
222 qtestcase 'VALUE_RANGE 0 201511 201511~' START.0=20151101 END.0=20151130
223 qtestcase 'VALUE_RANGE 0 201511 2015112~' START.0=20151101 END.0=20151129
224 qtestcase 'VALUE_RANGE 0 201512 2015~' START.0=20151201 END.0=20151231
225 qtestcase 'VALUE_RANGE 0 201512 20151230~' START.0=20151201 END.0=20151230
227 # Forward spans:
228 qtestcase 'VALUE_RANGE 0 20151104 20151106~' START.0=20151104 SPAN.0=3
229 qtestcase 'VALUE_RANGE 0 20141104 20151103~' START.0=20141104 SPAN.0=365
231 # Backward spans:
232 qtestcase 'VALUE_RANGE 0 20151104 20151106~' END.0=20151106 SPAN.0=3
233 qtestcase 'VALUE_RANGE 0 20141104 20151103~' END.0=20151103 SPAN.0=365
235 # Empty spans:
236 qtestcase '' START.0=20180919 END.0=19991225
237 # Check that the empty span dominates other spans:
238 qtestcase '' START.0=20180919 END.0=19991225 START.1=20180901
239 # Check that the empty span dominates a filter term:
240 qtestcase '' START.0=20180919 END.0=19991225 B=Ktag
241 # Check that the empty span dominates a negated filter term:
242 qtestcase '' START.0=20180919 END.0=19991225 N=Kneg
243 # Check that the empty span dominates a term-based date range filter:
244 qtestcase '' START.0=20180919 END.0=19991225 START=20000101 END=20001231
246 # Check that if START, END and SPAN are all passed, START is ignored:
247 qtestcase 'VALUE_RANGE 0 20151104 20151106~' START.0=19700101 END.0=20151106 SPAN.0=3
249 # Check multiple .SLOT filters:
250 qtestcase '(VALUE_RANGE 0 201512 2015~ AND VALUE_LE 5 1974~)' START.0=20151201 END.0=20151231 END.5=1974
252 # Check .SLOT and old-style value date range filter:
253 qtestcase '(VALUE_RANGE 0 201512 2015~ AND VALUE_LE 5 1974~)' START.0=20151201 END.0=20151231 DATEVALUE=5 END=1974
255 # Check .SLOT and old-style value date range filter on same slot.
256 # (We don't promise anything for this case, but it shouldn't crash).
257 qtestcase '(VALUE_RANGE 0 201512 2015~ AND VALUE_LE 0 1974~)' START.0=20151201 END.0=20151231 DATEVALUE=0 END=1974
259 # Tests of term-based date range filtering:
261 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999) OR Dlatest)' END=19991231
262 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989) OR Dlatest)' END=19891231
263 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974) OR Dlatest)' END=19741231
264 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR M198701 OR M198702 OR M198703 OR M198704 OR M198705 OR M198706 OR M198707 OR M198708 OR M198709) OR Dlatest)' END=19870930
265 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR Y2000 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR M201511) OR Dlatest)' END=20151130
266 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR M198401 OR M198402 OR M198403 OR D19840401) OR Dlatest)' END=19840401
267 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR M198801 OR M198802 OR M198803 OR M198804 OR M198805 OR M198806 OR M198807 OR M198808 OR M198809 OR M198810 OR D19881101 OR D19881102 OR D19881103 OR D19881104 OR D19881105 OR D19881106 OR D19881107 OR D19881108 OR D19881109 OR D19881110 OR D19881111 OR D19881112 OR D19881113 OR D19881114 OR D19881115 OR D19881116 OR D19881117 OR D19881118 OR D19881119 OR D19881120 OR D19881121 OR D19881122 OR D19881123 OR D19881124 OR D19881125 OR D19881126 OR D19881127 OR D19881128) OR Dlatest)' END=19881128
269 # Leap year tests:
270 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR Y2000 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502) OR Dlatest)' END=20150228
271 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR M198801 OR M198802) OR Dlatest)' END=19880229
272 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR M198801 OR D19880201 OR D19880202 OR D19880203 OR D19880204 OR D19880205 OR D19880206 OR D19880207 OR D19880208 OR D19880209 OR D19880210 OR D19880211 OR D19880212 OR D19880213 OR D19880214 OR D19880215 OR D19880216 OR D19880217 OR D19880218 OR D19880219 OR D19880220 OR D19880221 OR D19880222 OR D19880223 OR D19880224 OR D19880225 OR D19880226 OR D19880227 OR D19880228) OR Dlatest)' END=19880228
273 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR M200001 OR M200002) OR Dlatest)' END=20000229
274 qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR M200001 OR D20000201 OR D20000202 OR D20000203 OR D20000204 OR D20000205 OR D20000206 OR D20000207 OR D20000208 OR D20000209 OR D20000210 OR D20000211 OR D20000212 OR D20000213 OR D20000214 OR D20000215 OR D20000216 OR D20000217 OR D20000218 OR D20000219 OR D20000220 OR D20000221 OR D20000222 OR D20000223 OR D20000224 OR D20000225 OR D20000226 OR D20000227 OR D20000228) OR Dlatest)' END=20000228
275 # FIXME: These two currently require 64-bit time_t:
276 #qtestcase 'Dlatest' END=19000228 # Assumed start is 19700101
277 #qtestcase '((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR Y2000 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR Y2015 OR Y2016 OR Y2017 OR Y2018 OR Y2019 OR Y2020 OR Y2021 OR Y2022 OR Y2023 OR Y2024 OR Y2025 OR Y2026 OR Y2027 OR Y2028 OR Y2029 OR Y2030 OR Y2031 OR Y2032 OR Y2033 OR Y2034 OR Y2035 OR Y2036 OR Y2037 OR Y2038 OR Y2039 OR Y2040 OR Y2041 OR Y2042 OR Y2043 OR Y2044 OR Y2045 OR Y2046 OR Y2047 OR Y2048 OR Y2049 OR Y2050 OR Y2051 OR Y2052 OR Y2053 OR Y2054 OR Y2055 OR Y2056 OR Y2057 OR Y2058 OR Y2059 OR Y2060 OR Y2061 OR Y2062 OR Y2063 OR Y2064 OR Y2065 OR Y2066 OR Y2067 OR Y2068 OR Y2069 OR Y2070 OR Y2071 OR Y2072 OR Y2073 OR Y2074 OR Y2075 OR Y2076 OR Y2077 OR Y2078 OR Y2079 OR Y2080 OR Y2081 OR Y2082 OR Y2083 OR Y2084 OR Y2085 OR Y2086 OR Y2087 OR Y2088 OR Y2089 OR Y2090 OR Y2091 OR Y2092 OR Y2093 OR Y2094 OR Y2095 OR Y2096 OR Y2097 OR Y2098 OR Y2099 OR M210001 OR M210002) OR Dlatest)' END=21000228
279 # Month starts and ends:
280 qtestcase '(M201501 OR Dlatest)' START=20150101 END=20150131
281 qtestcase '((D20150101 OR D20150102 OR D20150103 OR D20150104 OR D20150105 OR D20150106 OR D20150107 OR D20150108 OR D20150109 OR D20150110 OR D20150111 OR D20150112 OR D20150113 OR D20150114 OR D20150115 OR D20150116 OR D20150117 OR D20150118 OR D20150119 OR D20150120 OR D20150121 OR D20150122 OR D20150123 OR D20150124 OR D20150125 OR D20150126 OR D20150127 OR D20150128 OR D20150129 OR D20150130) OR Dlatest)' START=20150101 END=20150130
282 qtestcase '(M201502 OR Dlatest)' START=20150201 END=20150228
283 qtestcase '((D20150201 OR D20150202 OR D20150203 OR D20150204 OR D20150205 OR D20150206 OR D20150207 OR D20150208 OR D20150209 OR D20150210 OR D20150211 OR D20150212 OR D20150213 OR D20150214 OR D20150215 OR D20150216 OR D20150217 OR D20150218 OR D20150219 OR D20150220 OR D20150221 OR D20150222 OR D20150223 OR D20150224 OR D20150225 OR D20150226 OR D20150227) OR Dlatest)' START=20150201 END=20150227
284 qtestcase '(M201503 OR Dlatest)' START=20150301 END=20150331
285 qtestcase '((D20150301 OR D20150302 OR D20150303 OR D20150304 OR D20150305 OR D20150306 OR D20150307 OR D20150308 OR D20150309 OR D20150310 OR D20150311 OR D20150312 OR D20150313 OR D20150314 OR D20150315 OR D20150316 OR D20150317 OR D20150318 OR D20150319 OR D20150320 OR D20150321 OR D20150322 OR D20150323 OR D20150324 OR D20150325 OR D20150326 OR D20150327 OR D20150328 OR D20150329 OR D20150330) OR Dlatest)' START=20150301 END=20150330
286 qtestcase '(M201504 OR Dlatest)' START=20150401 END=20150430
287 qtestcase '((D20150401 OR D20150402 OR D20150403 OR D20150404 OR D20150405 OR D20150406 OR D20150407 OR D20150408 OR D20150409 OR D20150410 OR D20150411 OR D20150412 OR D20150413 OR D20150414 OR D20150415 OR D20150416 OR D20150417 OR D20150418 OR D20150419 OR D20150420 OR D20150421 OR D20150422 OR D20150423 OR D20150424 OR D20150425 OR D20150426 OR D20150427 OR D20150428 OR D20150429) OR Dlatest)' START=20150401 END=20150429
288 qtestcase '(M201505 OR Dlatest)' START=20150501 END=20150531
289 qtestcase '((D20150501 OR D20150502 OR D20150503 OR D20150504 OR D20150505 OR D20150506 OR D20150507 OR D20150508 OR D20150509 OR D20150510 OR D20150511 OR D20150512 OR D20150513 OR D20150514 OR D20150515 OR D20150516 OR D20150517 OR D20150518 OR D20150519 OR D20150520 OR D20150521 OR D20150522 OR D20150523 OR D20150524 OR D20150525 OR D20150526 OR D20150527 OR D20150528 OR D20150529 OR D20150530) OR Dlatest)' START=20150501 END=20150530
290 qtestcase '(M201506 OR Dlatest)' START=20150601 END=20150630
291 qtestcase '((D20150601 OR D20150602 OR D20150603 OR D20150604 OR D20150605 OR D20150606 OR D20150607 OR D20150608 OR D20150609 OR D20150610 OR D20150611 OR D20150612 OR D20150613 OR D20150614 OR D20150615 OR D20150616 OR D20150617 OR D20150618 OR D20150619 OR D20150620 OR D20150621 OR D20150622 OR D20150623 OR D20150624 OR D20150625 OR D20150626 OR D20150627 OR D20150628 OR D20150629) OR Dlatest)' START=20150601 END=20150629
292 qtestcase '(M201507 OR Dlatest)' START=20150701 END=20150731
293 qtestcase '((D20150701 OR D20150702 OR D20150703 OR D20150704 OR D20150705 OR D20150706 OR D20150707 OR D20150708 OR D20150709 OR D20150710 OR D20150711 OR D20150712 OR D20150713 OR D20150714 OR D20150715 OR D20150716 OR D20150717 OR D20150718 OR D20150719 OR D20150720 OR D20150721 OR D20150722 OR D20150723 OR D20150724 OR D20150725 OR D20150726 OR D20150727 OR D20150728 OR D20150729 OR D20150730) OR Dlatest)' START=20150701 END=20150730
294 qtestcase '(M201508 OR Dlatest)' START=20150801 END=20150831
295 qtestcase '((D20150801 OR D20150802 OR D20150803 OR D20150804 OR D20150805 OR D20150806 OR D20150807 OR D20150808 OR D20150809 OR D20150810 OR D20150811 OR D20150812 OR D20150813 OR D20150814 OR D20150815 OR D20150816 OR D20150817 OR D20150818 OR D20150819 OR D20150820 OR D20150821 OR D20150822 OR D20150823 OR D20150824 OR D20150825 OR D20150826 OR D20150827 OR D20150828 OR D20150829 OR D20150830) OR Dlatest)' START=20150801 END=20150830
296 qtestcase '(M201509 OR Dlatest)' START=20150901 END=20150930
297 qtestcase '((D20150901 OR D20150902 OR D20150903 OR D20150904 OR D20150905 OR D20150906 OR D20150907 OR D20150908 OR D20150909 OR D20150910 OR D20150911 OR D20150912 OR D20150913 OR D20150914 OR D20150915 OR D20150916 OR D20150917 OR D20150918 OR D20150919 OR D20150920 OR D20150921 OR D20150922 OR D20150923 OR D20150924 OR D20150925 OR D20150926 OR D20150927 OR D20150928 OR D20150929) OR Dlatest)' START=20150901 END=20150929
298 qtestcase '(M201510 OR Dlatest)' START=20151001 END=20151031
299 qtestcase '((D20151001 OR D20151002 OR D20151003 OR D20151004 OR D20151005 OR D20151006 OR D20151007 OR D20151008 OR D20151009 OR D20151010 OR D20151011 OR D20151012 OR D20151013 OR D20151014 OR D20151015 OR D20151016 OR D20151017 OR D20151018 OR D20151019 OR D20151020 OR D20151021 OR D20151022 OR D20151023 OR D20151024 OR D20151025 OR D20151026 OR D20151027 OR D20151028 OR D20151029 OR D20151030) OR Dlatest)' START=20151001 END=20151030
300 qtestcase '(M201511 OR Dlatest)' START=20151101 END=20151130
301 qtestcase '((D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128 OR D20151129) OR Dlatest)' START=20151101 END=20151129
302 qtestcase '(M201512 OR Dlatest)' START=20151201 END=20151231
303 qtestcase '((D20151201 OR D20151202 OR D20151203 OR D20151204 OR D20151205 OR D20151206 OR D20151207 OR D20151208 OR D20151209 OR D20151210 OR D20151211 OR D20151212 OR D20151213 OR D20151214 OR D20151215 OR D20151216 OR D20151217 OR D20151218 OR D20151219 OR D20151220 OR D20151221 OR D20151222 OR D20151223 OR D20151224 OR D20151225 OR D20151226 OR D20151227 OR D20151228 OR D20151229 OR D20151230) OR Dlatest)' START=20151201 END=20151230
305 # Forward spans:
306 qtestcase '((D20151104 OR D20151105 OR D20151106 OR D20151107) OR Dlatest)' START=20151104 SPAN=3
307 qtestcase '((D20141104 OR D20141105 OR D20141106 OR D20141107 OR D20141108 OR D20141109 OR D20141110 OR D20141111 OR D20141112 OR D20141113 OR D20141114 OR D20141115 OR D20141116 OR D20141117 OR D20141118 OR D20141119 OR D20141120 OR D20141121 OR D20141122 OR D20141123 OR D20141124 OR D20141125 OR D20141126 OR D20141127 OR D20141128 OR D20141129 OR D20141130 OR M201412 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104) OR Dlatest)' START=20141104 SPAN=365
309 # Backward spans:
310 qtestcase '((D20151103 OR D20151104 OR D20151105 OR D20151106) OR Dlatest)' END=20151106 SPAN=3
311 qtestcase '((D20141103 OR D20141104 OR D20141105 OR D20141106 OR D20141107 OR D20141108 OR D20141109 OR D20141110 OR D20141111 OR D20141112 OR D20141113 OR D20141114 OR D20141115 OR D20141116 OR D20141117 OR D20141118 OR D20141119 OR D20141120 OR D20141121 OR D20141122 OR D20141123 OR D20141124 OR D20141125 OR D20141126 OR D20141127 OR D20141128 OR D20141129 OR D20141130 OR M201412 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103) OR Dlatest)' END=20151103 SPAN=365
313 # Check that if START, END and SPAN are all passed, START is ignored:
314 qtestcase '((D20151103 OR D20151104 OR D20151105 OR D20151106) OR Dlatest)' START=19700101 END=20151106 SPAN=3
316 # Check that YYYYMM and YYYY are accepted and handled appropriately:
317 qtestcase '((Y1980 OR Y1981) OR Dlatest)' START=1980 END=1981
318 qtestcase '((M198012 OR M198101 OR M198102) OR Dlatest)' START=198012 END=198102
320 # Check .SLOT combined with term based date range filter:
321 qtestcase '(VALUE_RANGE 0 201512 2015~ AND ((Y1970 OR Y1971 OR Y1972 OR Y1973 OR Y1974) OR Dlatest))' START.0=20151201 END.0=20151231 END=19741231
323 # Check combining of filter terms:
324 qtestcase '(Horg AND Len)' B=Len B=Horg
325 qtestcase '(Len OR Lde)' B=Len B=Lde
326 qtestcase '((Horg OR Hcom) AND (Len OR Lfr))' B=Len B=Lfr B=Horg B=Hcom
328 # Check combining of filter terms with filter_op set:
329 printf '$setmap{nonexclusiveprefix,L,1,XAND,1}$setmap{boolprefix,lang,L,and,XAND,host,H,year,Y}$querydescription' > "$TEST_TEMPLATE"
330 qtestcase 'Len' B=Len
331 qtestcase '0 * Len' P=lang:en
332 qtestcase 'XANDtest' B=XANDtest
333 qtestcase '0 * XANDtest' P=and:test
334 qtestcase '(Len AND XANDtest)' B=Len B=XANDtest
335 qtestcase '0 * (Len AND XANDtest)' P='lang:en and:test'
336 qtestcase '(Len AND Lde)' B=Len B=Lde
337 qtestcase '0 * (Len AND Lde)' P='lang:en lang:de'
338 qtestcase '((Horg OR Hcom) AND (Len AND Lfr))' B=Len B=Lfr B=Horg B=Hcom
339 qtestcase '0 * ((Len AND Lfr) AND (Horg OR Hcom))' P='lang:en lang:fr host:org host:com'
340 qtestcase '((XANDa AND XANDb AND XANDc) AND (Y1998 OR Y2001))' B=Y1998 B=Y2001 B=XANDa B=XANDb B=XANDc
341 qtestcase '0 * (((XANDa AND XANDb) AND XANDc) AND (Y1998 OR Y2001))' P='year:1998 year:2001 and:a and:b and:c'
343 # Check combining of filters around CGI parameter 'N':
344 qtestcase '(Ztruth@1 AND_NOT Epdf)' P=truth N=Epdf
345 qtestcase '(Ztruth@1 AND_NOT (Ehtm OR Epdf))' P=truth N=Epdf N=Ehtm
346 qtestcase '(Ztruth@1 AND_NOT (Ehtm OR Epdf OR Lde OR Lfr))' P=truth N=Lfr N=Epdf N=Ehtm N=Lde
347 qtestcase '((Ztruth@1 FILTER (Lfr AND Lzh)) AND_NOT (Lde OR Len))' P=truth N=Lde N=Len B=Lfr B=Lzh
348 qtestcase '((Ztruth@1 FILTER Lfr) AND_NOT (Ehtm OR Epdf))' P=truth N=Epdf N=Ehtm B=Lfr
349 qtestcase '(<alldocuments> AND_NOT (Len OR Lfr))' N=Lfr N=Len
350 qtestcase '(VALUE_RANGE 0 2015 201501~ AND_NOT Len)' DATEVALUE=0 START=20150101 END=20150131 N=Len
352 # If faketime is available and works, test cases where the output depends on
353 # "now".
354 rc=0
355 out=`faketime -f '1980-12-08 00:00:00' date +%Y 2>&1` || rc=$?
356 if [ "$rc:$out" = "0:1980" ] ; then
357 TZ=UTC
358 export TZ
359 FAKETIME='faketime -f'
360 FAKE_NOW='2015-11-28 06:07:08'
361 qtestcase 'VALUE_RANGE 0 20151127060709 20151128060708' DATEVALUE=0 SPAN=1
363 # Tests of term-based date range filtering:
364 qtestcase '((Y2000 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=20000101
365 qtestcase '((Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=20100101
366 qtestcase '((Y1974 OR Y1975 OR Y1976 OR Y1977 OR Y1978 OR Y1979 OR Y1980 OR Y1981 OR Y1982 OR Y1983 OR Y1984 OR Y1985 OR Y1986 OR Y1987 OR Y1988 OR Y1989 OR Y1990 OR Y1991 OR Y1992 OR Y1993 OR Y1994 OR Y1995 OR Y1996 OR Y1997 OR Y1998 OR Y1999 OR Y2000 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=19740101
367 qtestcase '((M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=20151001
368 # Date range with start after end:
369 qtestcase 'Dlatest' START=201512
370 qtestcase 'Dlatest' START=20151201
371 qtestcase '((D20150210 OR D20150211 OR D20150212 OR D20150213 OR D20150214 OR D20150215 OR D20150216 OR D20150217 OR D20150218 OR D20150219 OR D20150220 OR D20150221 OR D20150222 OR D20150223 OR D20150224 OR D20150225 OR D20150226 OR D20150227 OR D20150228 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=20150210
372 qtestcase '((D20000220 OR D20000221 OR D20000222 OR D20000223 OR D20000224 OR D20000225 OR D20000226 OR D20000227 OR D20000228 OR D20000229 OR M200003 OR M200004 OR M200005 OR M200006 OR M200007 OR M200008 OR M200009 OR M200010 OR M200011 OR M200012 OR Y2001 OR Y2002 OR Y2003 OR Y2004 OR Y2005 OR Y2006 OR Y2007 OR Y2008 OR Y2009 OR Y2010 OR Y2011 OR Y2012 OR Y2013 OR Y2014 OR M201501 OR M201502 OR M201503 OR M201504 OR M201505 OR M201506 OR M201507 OR M201508 OR M201509 OR M201510 OR D20151101 OR D20151102 OR D20151103 OR D20151104 OR D20151105 OR D20151106 OR D20151107 OR D20151108 OR D20151109 OR D20151110 OR D20151111 OR D20151112 OR D20151113 OR D20151114 OR D20151115 OR D20151116 OR D20151117 OR D20151118 OR D20151119 OR D20151120 OR D20151121 OR D20151122 OR D20151123 OR D20151124 OR D20151125 OR D20151126 OR D20151127 OR D20151128) OR Dlatest)' START=20000220
373 FAKETIME=
374 unset FAKE_NOW
375 else
376 if [ "$rc" = 127 ] ; then
377 echo "Skipping testcases which need 'faketime' tool installed"
378 else
379 echo "Skipping testcases which need 'faketime' tool - it's installed but doesn't work"
383 # Test stem_all and stem_strategy.
384 printf '$if{$cgi{stem_all},$set{stem_all,$cgi{stem_all}}}$if{$cgi{stem_strategy},$set{stem_strategy,$cgi{stem_strategy}}}$querydescription' > "$TEST_TEMPLATE"
385 qtestcase '((capitalised@1 AND tests@2) AND Zstem@3)' P='Capitalised "tests" stemmed'
386 qtestcase '(nearing@1 NEAR 11 distances@2)' P='nearing NEAR distances'
387 qtestcase '((capitalis@1 AND test@2) AND stem@3)' P='Capitalised "tests" stemmed' stem_all=true
388 qtestcase '(near@1 NEAR 11 distanc@2)' P='nearing NEAR distances' stem_all=true
389 qtestcase '((capitalis@1 AND test@2) AND stem@3)' P='Capitalised "tests" stemmed' stem_strategy=all
390 qtestcase '(near@1 NEAR 11 distanc@2)' P='nearing NEAR distances' stem_strategy=all
391 qtestcase '((Zcapitalis@1 AND Ztest@2) AND Zstem@3)' P='Capitalised "tests" stemmed' stem_strategy=all_z
392 qtestcase '(Znear@1 NEAR 11 Zdistanc@2)' P='nearing NEAR distances' stem_strategy=all_z
393 qtestcase '((capitalised@1 AND tests@2) AND stemmed@3)' P='Capitalised "tests" stemmed' stem_strategy=none
394 qtestcase '(nearing@1 NEAR 11 distances@2)' P='nearing NEAR distances' stem_strategy=none
395 qtestcase '((capitalised@1 AND tests@2) AND Zstem@3)' P='Capitalised "tests" stemmed' stem_strategy=some
396 qtestcase '(nearing@1 NEAR 11 distances@2)' P='nearing NEAR distances' stem_strategy=some
397 qtestcase '((capitalised@1 AND tests@2) AND Zstem@3)' P='Capitalised "tests" stemmed' stem_strategy=some_full_pos
398 qtestcase '(Znear@1 NEAR 11 Zdistanc@2)' P='nearing NEAR distances' stem_strategy=some_full_pos
399 qtestcase '((capitalised@1 AND tests@2) AND Zstem@3)' P='Capitalised "tests" stemmed' stem_strategy=some stem_all=true
400 qtestcase '(nearing@1 NEAR 11 distances@2)' P='nearing NEAR distances' stem_strategy=some stem_all=true
402 # Feature tests for $contains.
403 printf '$contains{$cgi{a},$cgi{b}}' > "$TEST_TEMPLATE"
404 testcase '6' P=text a=fish b="Hello fish"
405 testcase '' P=text a="Example" b="random"
407 NEWLINE='
410 # Feature tests for boolprefix and prefix maps.
411 printf '$set{stemmer,}$setmap{boolprefix,lang,L,host,H}$setmap{prefix,,XDEFAULT}$querydescription' > "$TEST_TEMPLATE"
412 qtestcase '((XDEFAULTfoo@1 AND XDEFAULTbar@2) FILTER (Hexample.org AND Lzh))' P='host:example.org foo bar lang:zh'
414 # Feature tests for $cond.
415 printf '$cond{$cgi{one},1,$cgi{two},2,$cgi{three},3}' > "$TEST_TEMPLATE"
416 testcase '1' one=true
417 testcase '2' two=true
418 testcase '3' three=true
419 testcase '' nothing=true
420 testcase '1' one=true two=true three=true
421 testcase '2' two=true three=true
422 printf '$cond{$cgi{one},1,$cgi{two},2,$cgi{alt}}' > "$TEST_TEMPLATE"
423 testcase '1' one=true
424 testcase '2' two=true
425 testcase 'none' alt=none
426 # Check evaluation is lazy.
427 printf '$cond{$cgi{one},$seterror{err1},$cgi{two},2,$cgi{alt}}$error' > "$TEST_TEMPLATE"
428 testcase 'err1' one=true
429 testcase '2' two=true
430 testcase 'none' alt=none
431 printf '$cond{$cgi{one},1,$cgi{two},$seterror{err2},$cgi{alt}}$error' > "$TEST_TEMPLATE"
432 testcase '1' one=true
433 testcase 'err2' two=true
434 testcase 'none' alt=none
435 printf '$cond{$cgi{one},1,$cgi{two},2,$seterror{erralt}}$error' > "$TEST_TEMPLATE"
436 testcase '1' one=true
437 testcase '2' two=true
438 testcase 'erralt' alt=none
440 # Feature tests for $switch.
441 printf '$switch{$cgi{x},1,one,2,two}' > "$TEST_TEMPLATE"
442 testcase 'one' x=1
443 testcase 'two' x=2
444 testcase '' x=3
445 printf '$switch{$cgi{x},1,one,2,two,default}' > "$TEST_TEMPLATE"
446 testcase 'one' x=1
447 testcase 'two' x=2
448 testcase 'default' x=3
449 # Check evaluation is lazy.
450 printf '$switch{$cgi{x},1,$seterror{err1},2,two}$error' > "$TEST_TEMPLATE"
451 testcase 'err1' x=1
452 testcase 'two' x=2
453 testcase '' x=3
454 printf '$switch{$cgi{x},1,one,2,$seterror{err2},default}$error' > "$TEST_TEMPLATE"
455 testcase 'one' x=1
456 testcase 'err2' x=2
457 testcase 'default' x=3
458 printf '$switch{$cgi{x},1,one,2,two,$seterror{errdefault}}$error' > "$TEST_TEMPLATE"
459 testcase 'one' x=1
460 testcase 'two' x=2
461 testcase 'errdefault' x=3
463 # Feature tests for $map.
464 printf '$list{$map{$split{-,$cgi{a}},$list{$map{$split{,$cgi{b}},$_},-}},|}' > "$TEST_TEMPLATE"
465 testcase '1-2-3|1-2-3' P=text a=ab-cd b=123
466 printf '$list{$map{$split{-,$cgi{a}},$set{__,$_}$list{$map{$split{,$cgi{b}},$opt{__}$_},-}},|}' > "$TEST_TEMPLATE"
467 testcase 'a1-a2-a3|b1-b2-b3' P=text a=a-b b=123
468 printf '$list{$map{$split{-,$cgi{a}},$list{$map{$split{$_,$cgi{b}},$_},-}},|}' > "$TEST_TEMPLATE"
469 testcase '1-2,3|1:2-3' P=text a=':-,' b='1:2,3'
470 # Check that the outer $_ is restored after the inner $map.
471 printf '$list{$map{$split{-,$cgi{a}},$list{$map{$split{,$cgi{b}},$_},-}$_},|}' > "$TEST_TEMPLATE"
472 testcase '1-2-3a|1-2-3b' P=text a='a-b' b='123'
474 # Feature tests for $match.
475 printf '$match{$cgi{a},$cgi{b},$cgi{c}}' > "$TEST_TEMPLATE"
476 testcase 'true' P=text a="ab*c+" b="ac"
477 testcase '' P=text a="acb" b="abc"
478 testcase 'true' P=text a="[A-Z]bcD" b="abcd" c="i"
479 testcase '' P=text a="[A-Z]bcD" b="abcd"
480 testcase 'true' P=text a="^abc$" b="${NEWLINE}abc${NEWLINE}def" c="m"
481 testcase '' P=text a="^abc$" b="${NEWLINE}abc${NEWLINE}def"
482 testcase 'true' P=text a="abc." b="abc${NEWLINE}" c="s"
483 testcase '' P=text a="abc." b="abc${NEWLINE}"
484 testcase 'true' P=text a=" ABC #test_comment " b="ABC" c="x"
485 testcase '' P=text a=" ABC #test_comment " b="ABC"
487 # Feature tests for $sort.
488 printf '$list{$sort{$split{|,$cgi{input}}},|}' > "$TEST_TEMPLATE"
489 testcase 'pineapple' input="pineapple"
490 testcase 'apple|banana|coconut' input="coconut|banana|apple"
491 testcase '1|b|b|c' input="b|c|b|1"
492 printf '$list{$sort{$split{|,$cgi{input}},$cgi{opt}},|}' > "$TEST_TEMPLATE"
493 testcase 'pineapple' input="pineapple" opt=
494 testcase 'pineapple' input="pineapple" opt=r
495 testcase 'pineapple' input="pineapple" opt=ru
496 testcase '1|b|c' input="b|c|b|1" opt=u
497 testcase 'c|b|b|1' input="b|c|b|1" opt=r
498 testcase 'c|b|1' input="b|c|b|1" opt=ur
499 testcase '-2|-.01|+99.99|+999|.0|0.0|.1|1|2|3|3.0|3.01|12|23|30' input='+999|2|1|12|23|3|30|3.01|3.0|.1|.0|0.0|-2|-.01|+99.99' opt=n
500 testcase '-2|-.01|+999|.1|1|2|3|3.01|12|23|30' input='+999|2|1|12|23|3|30|3.01|3.0|.1|.0|0.0|-2|-.01|+99.99' opt=nu
501 testcase '-2|-.01|+99.99|.1|1|2|3.0|3.01|12|23|30' input='+99.99|-.01|-2|0.0|.0|.1|3.0|3.01|30|3|23|12|1|2|+999' opt=nu
502 testcase '30|23|12|3.01|3.0|3|2|1|.1|0.0|.0|+999|+99.99|-.01|-2' input='+999|2|1|12|23|3|30|3.01|3.0|.1|.0|0.0|-2|-.01|+99.99' opt=nr
503 testcase '30|23|12|3.01|3|2|1|.1|+999|-.01|-2' input='+999|2|1|12|23|3|30|3.01|3.0|.1|.0|0.0|-2|-.01|+99.99' opt=nur
504 testcase '30|23|12|3.01|3.0|2|1|.1|+99.99|-.01|-2' input='+99.99|-.01|-2|0.0|.0|.1|3.0|3.01|30|3|23|12|1|2|+999' opt=nur
505 testcase 't 42|t 42:|t 42:1|t 42:09|t 42:9|t 42:11|t 42~' input='t 42:1|t 42|t 42:11|t 42:9|t 42~|t 42:|t 42:09' opt='#'
506 testcase 'A7R1:2|A7R2:6|A7R2:9|A7R2:11|A7R2:19|A7R2:47A|A7R11:1|AA|R7:1.09|R7:4A|R7:6|R7:7A|R7:404|R7:444-10|R7:1521' \
507 input='A7R1:2|R7:1521|AA|R7:4A|R7:7A|A7R2:9|R7:444-10|A7R2:6|R7:1.09|A7R2:47A|A7R11:1|R7:6|A7R2:11|R7:404|A7R2:19' \
508 opt='#'
509 testcase '30|23|12|3|03|2|1|01|0|00' input='2|1|23|12|23|3|30|0|00|0|01|03' opt='#ru'
510 testcase 'Exception: Unknown $sort option: x' input="b|c|b|1" opt=urx
511 testcase 'Exception: Invalid $sort option combination: n#' input="b|c" opt='n#'
512 testcase 'Exception: Invalid $sort option combination: #rn' input="b|1" opt='#rn'
514 # Feature tests for $terms.
515 printf 'text : index\nhost : boolean=H\nfoo : boolean=XFOO' > "$TEST_INDEXSCRIPT"
516 rm -rf "$TEST_DB"
517 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
518 text=This is some text.
519 host=example.org
520 foo=bar
522 printf '$hitlist{$list{$if{$eq{$cgi{prefix},null},$terms,$terms{$cgi{prefix}}},|}}' > "$TEST_TEMPLATE"
523 testcase 'Ztext' P=text B=Hexample.org B=Hexample.com prefix=null
524 testcase 'Hexample.org|Ztext' P=text B=Hexample.org B=Hexample.com prefix=
525 testcase 'Hexample.org' P=text B=Hexample.org B=Hexample.com prefix=H
526 testcase 'Ztext' P=text B=Hexample.org B=Hexample.com prefix=Z
527 testcase '' P=text B=Hexample.org B=Hexample.com prefix=E
529 printf '$msizelower $msize $msizeupper $msizeexact' > "$TEST_TEMPLATE"
530 testcase '1 1 1 true' P=this
531 testcase '1 1 1 true' P='Some text'
532 testcase '0 0 0 true' P=potato
534 printf '$set{weighting,coord}$hitlist{$weight.}' > "$TEST_TEMPLATE"
535 testcase '' P=aardvark
536 testcase '1.000000.' P=texting
537 testcase '' P='texting while driving'
538 testcase '' P='texting while driving' DEFAULTOP=AND
539 testcase '1.000000.' P='texting while driving' DEFAULTOP=OR
540 testcase '2.000000.' P='Some text'
541 # "this" and "is" are stopwords.
542 testcase '2.000000.' P='This is some text'
543 testcase '4.000000.' P='"This" "is" some text'
544 testcase '4.000000.' P='+This +is some text'
545 testcase '4.000000.' P='"This is some text"'
547 printf '$set{weightingpurefilter,coord}$hitlist{$weight.}' > "$TEST_TEMPLATE"
548 testcase '' B=XFOOfoo
549 testcase '1.000000.' B=Hexample.org
550 testcase '' B=Hexample.org B=XFOOfoo
551 testcase '1.000000.' B=Hexample.org B=Hexample.net
552 testcase '2.000000.' B=Hexample.org B=XFOObar
553 testcase '3.000000.' B=Hexample.org B=XFOObar B=XFOObar
555 printf '$filters' > "$TEST_TEMPLATE"
556 testcase 'Hexample.net~Hexample.org~.~~' B=Hexample.org B=Hexample.net
557 testcase '!Gmisc.test~.~~' N=Gmisc.test
558 testcase 'Hexample.net~Hexample.org~!Gmisc.test~.~~' B=Hexample.org B=Hexample.net N=Gmisc.test
559 testcase '.20040612~~~1~' DATEVALUE=1 START=20040612
560 testcase '.20040612~~~1~2' DATEVALUE=1 START=20040612 COLLAPSE=2
561 testcase '.20040612~~30~2' START=20040612 SPAN=30 COLLAPSE=2
562 testcase '.20040612~20160412~' START=20040612 END=20160412
563 testcase '.~~~2' COLLAPSE=2
564 testcase '.~~'
565 testcase '.~~1' SORT=1
566 testcase '.~~1f' SORT=+1
567 testcase '.~~1' SORT=-1
568 testcase '.~~1-2+3-27' SORT=+1-2+03,-27
569 testcase '.~~' SORTREVERSE=1
570 testcase '.~~1f' SORT=1 SORTREVERSE=1
571 testcase '.~~1' SORT=+1 SORTREVERSE=1
572 testcase '.~~1f' SORT=-1 SORTREVERSE=1
573 testcase '.~~1-2+3-27f' SORT=+1-2+03,-27 SORTREVERSE=1
574 testcase '.~~' SORTAFTER=1
575 testcase '.~~1R' SORT=1 SORTAFTER=1
576 testcase '.~~1F' SORT=+1 SORTAFTER=1
577 testcase '.~~1R' SORT=-1 SORTAFTER=1
578 testcase '.~~1-2+3-27R' SORT=+1-2+03,-27 SORTAFTER=1
579 testcase '.~~' SORTREVERSE=1 SORTAFTER=1
580 testcase '.~~1F' SORT=1 SORTREVERSE=1 SORTAFTER=1
581 testcase '.~~1R' SORT=+1 SORTREVERSE=1 SORTAFTER=1
582 testcase '.~~1F' SORT=-1 SORTREVERSE=1 SORTAFTER=1
583 testcase '.~~1-2+3-27F' SORT=+1-2+03,-27 SORTREVERSE=1 SORTAFTER=1
584 testcase '.~~X' DOCIDORDER=A # Buggy, but kept for compatibility.
585 testcase '.~~D' DOCIDORDER=D
586 testcase '.~~' DOCIDORDER=X # Buggy, but kept for compatibility.
587 testcase '.~~' DOCIDORDER=x # Buggy, but kept for compatibility.
589 tab=`printf '\t'`
590 printf '$cgi{AZ}|$cgi{AZ B}|$cgi{AZ.x}|$cgi{AZ.y}|$cgi{[}|$cgi{#}' > "$TEST_TEMPLATE"
591 testcase 'AZ|||||' AZ.x=3 AZ.y=4
592 testcase 'B|||||' 'AZ B.x=5' 'AZ B.y=12'
593 testcase 'B|||||' "AZ${tab}B.x=5" "AZ${tab}B.y=12"
594 testcase '||||2 ]|' '[ 2 ].x=123'
595 testcase '||||2 ]|' "[${tab}2 ].x=123"
596 testcase "||||2${tab}]|" "[ 2${tab}].x=123"
597 testcase "||||2${tab}]|" "[${tab}2${tab}].x=123"
598 testcase '|||||12' '12.x=37'
599 testcase 'DE|||||' 'AZ BC=DE'
600 testcase 'DE|||||' 'AZ B C=DE'
601 testcase 'DE|||||' "AZ${tab}BC=DE"
602 testcase 'DE|||||' "AZ B${tab}C=DE"
603 testcase 'DE|||||' "AZ${tab}B C=DE"
604 testcase 'DE|||||' "AZ${tab}B${tab}C=DE"
606 printf '$cgi{Search}|$cgi{Type}|$cgi{Search Type}' > "$TEST_TEMPLATE"
607 testcase 'Discover-List||' 'Search Type=Discover-List'
609 printf '$cgiparams' > "$TEST_TEMPLATE"
610 # We can't test the "no cgi parameters" case via testcase, as it passes a
611 # "dummy" parameter if there aren't any real ones.
612 #testcase ""
613 testcase "" =1
614 testcase "ABC" ABC=1
615 testcase "ABC" ABC=1 ABC=2
616 testcase "A${tab}AZ${tab}Z" A=1 A=2 A=3 AZ=1 AZ=2 Z=xxx
617 testcase "${tab}abc" =1 abc=1
618 testcase "${tab}abc${tab}def" =1 abc=1 def=7
620 # Feature tests for $highlight{}.
621 printf '$highlight{$cgi{text},$cgi{list}}' > "$TEST_TEMPLATE"
622 testcase 'A <b style="color:black;background-color:#ffff66">list</b> of <b style="color:black;background-color:#99ff99">words</b>' list="list${tab}words" text="A list of words"
624 printf '$highlight{$cgi{text},$cgi{list},$cgi{open}}' > "$TEST_TEMPLATE"
625 testcase 'A list of <b>words</b>' list="words" text="A list of words" open="<b>"
626 testcase 'A list of <span>words</span>' list="words" text="A list of words" open="<span>"
628 printf '$highlight{$cgi{text},$cgi{list},$cgi{open},$cgi{close}}' > "$TEST_TEMPLATE"
629 testcase 'A list of <b>words</b>' list="words" text="A list of words" open="<b>" close="</b>"
630 testcase 'A *list* of *words*' list="words${tab}list" text="A list of words" open="*" close="*"
632 # Test setting seterror and mset size, should not run the query after setting error.
633 printf '$if{$cgi{ERR},$seterror{$cgi{ERR}}}$msize$if{$error,!$error!}' > "$TEST_TEMPLATE"
634 testcase '1' P=text
635 testcase '0!boo!' P=text ERR=boo
637 # Test arguments inside seterror are evaluated
638 printf '$set{error,sample error}$seterror{$opt{error}}$msize$if{$error,!$error!}' > "$TEST_TEMPLATE"
639 testcase '0!sample error!' P=text
641 # Test error message doesn't get sent through HTML entity encoding.
642 printf '$seterror{{ "error": true, "error_message": "Parameter cannot be > 9" }}$if{$error,$error}' > "$TEST_TEMPLATE"
643 testcase '{ "error": true, "error_message": "Parameter cannot be > 9" }' P=text
645 # Test msize when error set after running query, should not affect running of query.
646 printf '$last$if{$cgi{ERR},$seterror{$cgi{ERR}}}$msize$if{$error,!$error!}' > "$TEST_TEMPLATE"
647 testcase '11' P=text
648 testcase '11!boo!' P=text ERR=boo
650 # Feature tests for $hash{}
651 printf '$hash{$cgi{text},md5}' > "$TEST_TEMPLATE"
652 testcase '098f6bcd4621d373cade4e832627b4f6' text="test"
653 testcase 'b4c216e4da73d1d01277ef46d0514821' text="simple query"
654 testcase 'd41d8cd98f00b204e9800998ecf8427e' text=""
655 testcase '3302c94d3500c3f695b7e09b7acd420d' text=" test "
657 # Regression test - original implementation truncated data at first zero byte.
658 printf '$hash{$cgi{text}$chr{0},md5}' > "$TEST_TEMPLATE"
659 testcase 'e2a3e68d23ce348b8f68b3079de3d4c9' text="test"
661 printf '$hash{$cgi{text},invalidhash}' > "$TEST_TEMPLATE"
662 testcase 'Exception: Unknown hash function: invalidhash' text="test"
664 # Feature tests for $uniq and $unique{}.
665 printf '$list{$uniq{$split{$cgi{text}}},:}|$list{$unique{$split{$cgi{text}}},:}' > "$TEST_TEMPLATE"
666 testcase '|' text=''
667 testcase 'foo|foo' text='foo'
668 testcase 'apple:banana:cherry|apple:banana:cherry' text='apple apple banana banana banana cherry'
669 testcase 'a:b:r:a:c:a:d:a:b:r:a|a:b:r:c:d' text='a b r a c a d a b r a'
670 testcase 'x:y:z:y|x:y:z' text='x y z z y'
672 # Regression test - $map with one argument wasn't rejected cleanly.
673 printf '$map{foo}' > "$TEST_TEMPLATE"
674 testcase 'Exception: too few arguments to $map'
676 # Feature tests for split command scriptindex.
677 printf 'STATUS : field split=| field=SPLITSTATUS\nSTATUS : field=x' > "$TEST_INDEXSCRIPT"
678 rm -rf "$TEST_DB"
679 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
680 STATUS=PENDING|REVIEW
682 printf '$field{STATUS,1}/$field{x,1}/$list{$field{SPLITSTATUS,1},$.}' > "$TEST_TEMPLATE"
683 testcase 'PENDING|REVIEW/PENDING|REVIEW/PENDING,REVIEW' P=text
685 # Feature tests for split dedup command scriptindex.
686 printf 'STATUS : field split=|,dedup field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
687 rm -rf "$TEST_DB"
688 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
689 STATUS=REVIEW|PENDING|PENDING|REVIEW
691 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},$.}' > "$TEST_TEMPLATE"
692 testcase 'REVIEW|PENDING|PENDING|REVIEW/REVIEW,PENDING' P=text
694 # Feature tests for split sort command scriptindex.
695 printf 'STATUS : field split=|,sort field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
696 rm -rf "$TEST_DB"
697 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
698 STATUS=REVIEW|PENDING|PENDING|REVIEW
700 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},$.}' > "$TEST_TEMPLATE"
701 testcase 'REVIEW|PENDING|PENDING|REVIEW/PENDING,PENDING,REVIEW,REVIEW' P=text
703 # Feature tests for split none command scriptindex.
704 printf 'STATUS : field split=|,none field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
705 rm -rf "$TEST_DB"
706 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
707 STATUS=REVIEW|PENDING|PENDING|REVIEW
709 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},$.}' > "$TEST_TEMPLATE"
710 testcase 'REVIEW|PENDING|PENDING|REVIEW/REVIEW,PENDING,PENDING,REVIEW' P=text
712 # Feature tests for split command scriptindex without operation argument.
713 printf 'STATUS : field split=| field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
714 rm -rf "$TEST_DB"
715 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
716 STATUS=PENDING|REVIEW|PENDING|REVIEW
718 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},$.}' > "$TEST_TEMPLATE"
719 testcase 'PENDING|REVIEW|PENDING|REVIEW/PENDING,REVIEW,PENDING,REVIEW' P=text
721 # Feature test for multi-character split delimiter.
722 printf 'STATUS : field split=$. field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
723 rm -rf "$TEST_DB"
724 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
725 STATUS=PENDING$.$.REVIEW,PENDING$.REVIEW
727 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},|}' > "$TEST_TEMPLATE"
728 testcase 'PENDING$.$.REVIEW,PENDING$.REVIEW/PENDING|REVIEW,PENDING|REVIEW' P=text
730 # Feature test for multi-character split delimiter with potential overlap.
731 printf 'STATUS : field split=:: field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
732 rm -rf "$TEST_DB"
733 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
734 STATUS=::Foo::::Bar:Baz:::Hello::
736 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},|}' > "$TEST_TEMPLATE"
737 testcase '::Foo::::Bar:Baz:::Hello::/Foo|Bar:Baz|:Hello' P=text
739 # Feature tests for split command with "," delimiter passed , with double quotes.
740 printf 'STATUS : field split="," field=SPLITSTATUS\n' > "$TEST_INDEXSCRIPT"
741 rm -rf "$TEST_DB"
742 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
743 STATUS=PENDING,REVIEW,PENDING,REVIEW
745 printf '$field{STATUS,1}/$list{$field{SPLITSTATUS,1},|}' > "$TEST_TEMPLATE"
746 testcase 'PENDING,REVIEW,PENDING,REVIEW/PENDING|REVIEW|PENDING|REVIEW' P=text
748 # Feature test for nested split command.
749 printf 'in : split=; field=one lower split="," field=two\nin : field' > "$TEST_INDEXSCRIPT"
750 rm -rf "$TEST_DB"
751 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
752 in=a,b,c;10,21,32;XY,YZ
754 printf '$field{in,1}/$list{$field{one,1},|}/$list{$field{two,1},|}' > "$TEST_TEMPLATE"
755 testcase 'a,b,c;10,21,32;XY,YZ/a,b,c|10,21,32|XY,YZ/a|b|c|10|21|32|xy|yz' P=text
757 # Feature tests for scriptindex hextobin action.
758 printf 'hex : hextobin value=0' > "$TEST_INDEXSCRIPT"
759 rm -rf "$TEST_DB"
760 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
761 hex=
763 hex=41
765 hex=54657374
767 hex=4b696C6c
769 printf '$list{$map{$split{$cgi{DOCIDS}},$value{0,$_}},|}' > "$TEST_TEMPLATE"
770 testcase '|A|Test|Kill' DOCIDS='1 2 3 4'
772 # Feature test error cases for scriptindex hextobin action.
773 rm -rf "$TEST_DB"
774 echo hex=7g |\
775 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" 2>&1 > /dev/null |\
776 grep -q ":1: error: hextobin: input must be all hex digits" ||\
777 { echo "scriptindex hextobin didn't give error for bad hex digit";\
778 failed=`expr $failed + 1`; }
779 echo hex=404 |\
780 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" 2>&1 > /dev/null |\
781 grep -q ":1: error: hextobin: input must have even length" ||\
782 { echo "scriptindex hextobin didn't give error for odd length hex string";\
783 failed=`expr $failed + 1`; }
784 testcase '7g|404' DOCIDS='1 2'
786 # Test useless action warnings.
787 printf 'foo : index weight=2' > "$TEST_INDEXSCRIPT"
788 rm -rf "$TEST_DB"
789 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
790 | grep -q ":1:13: warning: Index action 'weight' has no effect" ; then
791 : # OK
792 else
793 echo "scriptindex didn't give expected warning for useless 'weight' action"
794 failed=`expr $failed + 1`
796 printf 'foo : weight=2 weight=3 index' > "$TEST_INDEXSCRIPT"
797 rm -rf "$TEST_DB"
798 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
799 | grep -q ":1:7: warning: Index action 'weight' has no effect" ; then
800 : # OK
801 else
802 echo "scriptindex didn't give expected warning for useless 'weight' action"
803 failed=`expr $failed + 1`
805 printf 'foo : index lower' > "$TEST_INDEXSCRIPT"
806 rm -rf "$TEST_DB"
807 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
808 | grep -q ":1:13: warning: Index action 'lower' has no effect" ; then
809 : # OK
810 else
811 echo "scriptindex didn't give expected warning for useless 'lower' action"
812 failed=`expr $failed + 1`
815 # Test bad fieldname errors.
816 printf 'foo *bar : index' > "$TEST_INDEXSCRIPT"
817 rm -rf "$TEST_DB"
818 rc=0
819 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
820 if [ $rc -eq 0 ] ; then
821 echo "scriptindex didn't exit with non-zero return code on bad fieldname"
822 failed=`expr $failed + 1`
823 elif printf '%s' "$out" \
824 | grep -q ":1:5: error: field name must start with alphanumeric" ; then
825 : # OK
826 else
827 echo "scriptindex didn't give expected error for a bad fieldname"
828 failed=`expr $failed + 1`
830 printf 'foo b!ar : index' > "$TEST_INDEXSCRIPT"
831 rm -rf "$TEST_DB"
832 rc=0
833 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
834 if [ $rc -eq 0 ] ; then
835 echo "scriptindex didn't exit with non-zero return code on bad fieldname"
836 failed=`expr $failed + 1`
837 elif printf '%s' "$out" \
838 | grep -q ":1:6: error: bad character '!' in fieldname" ; then
839 : # OK
840 else
841 echo "scriptindex didn't give expected error for a bad fieldname"
842 failed=`expr $failed + 1`
845 # Test unwanted action argument.
846 printf 'foo : spell=test index' > "$TEST_INDEXSCRIPT"
847 rm -rf "$TEST_DB"
848 rc=0
849 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
850 if [ $rc -eq 0 ] ; then
851 echo "scriptindex didn't exit with non-zero return code on unwanted action argument"
852 failed=`expr $failed + 1`
853 elif printf '%s' "$out" \
854 | grep -q ":1:12: error: Index action 'spell' doesn't take an argument" ; then
855 : # OK
856 else
857 echo "scriptindex didn't give expected error for unwanted action argument"
858 failed=`expr $failed + 1`
861 # Test missing closing quote.
862 printf 'foo : index="XFOO' > "$TEST_INDEXSCRIPT"
863 rm -rf "$TEST_DB"
864 rc=0
865 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
866 if [ $rc -eq 0 ] ; then
867 echo "scriptindex didn't exit with non-zero return code for missing closing quote"
868 failed=`expr $failed + 1`
869 elif printf '%s' "$out" \
870 | grep -q ":1:18: error: No closing quote" ; then
871 : # OK
872 else
873 echo "scriptindex didn't give expected error for missing closing quote"
874 failed=`expr $failed + 1`
877 # Feature tests for termprefix and unprefix.
878 printf '$termprefix{$cgi{B}}|$unprefix{$cgi{B}}' > "$TEST_TEMPLATE"
879 testcase '|' B=''
880 testcase '|something' B='something'
881 testcase '|42' B='42'
882 testcase '|3bad' B='3bad'
883 testcase '|&something' B='&something'
884 testcase '|:something' B=':something'
885 testcase 'H|example.org' B='Hexample.org'
886 testcase 'K|tag' B='Ktag'
887 testcase 'K|Capital' B='KCapital'
888 testcase 'K|:colon-tag' B='K:colon-tag'
889 testcase 'K|:Capital' B='K:Capital'
890 testcase 'XCOLOUR|red' B='XCOLOURred'
891 testcase 'XPUNC|:colon' B='XPUNC::colon'
892 testcase 'XPUNC|internal:colon' B='XPUNC:internal:colon'
893 testcase 'XPUNC|:Colon' B='XPUNC::Colon'
894 testcase 'XCASE|Upper' B='XCASE:Upper'
895 testcase 'XCASE|TITLE' B='XCASE:TITLE'
896 testcase 'XNUM|42' B='XNUM42'
897 testcase 'XNUM|3bad' B='XNUM3bad'
899 # Test to make sure out generate_sample function in sample.cc
900 # Doesn't run into negative memory access
901 printf '$truncate{$cgi{input},$cgi{maxlen},$cgi{ind},$cgi{ind2}}$seterror{$opt{error}}' > "$TEST_TEMPLATE"
902 testcase 'w...' input='wwwwww' maxlen=4 ind='...' ind2='...'
903 testcase '' input='s' maxlen=0 ind='...' ind2='...'
905 # Simple tests of $subdb and $subid.
906 rm -rf "$TEST_DB"
907 printf 'inmemory' > "$TEST_DB"
908 printf 'inmemory' > "${TEST_DB}2"
909 printf '$subdb{$cgi{ID}}|$subid{$cgi{ID}}' > "$TEST_TEMPLATE"
910 testcase "$TEST_DB|1" ID=1
911 testcase "$TEST_DB|1" ID=1 DB="$TEST_DB/${TEST_DB}2"
912 testcase "${TEST_DB}2|1" ID=2 DB="$TEST_DB/${TEST_DB}2"
913 testcase "${TEST_DB}|2" ID=3 DB="$TEST_DB/${TEST_DB}2"
914 rm -rf "${TEST_DB}2"
916 # Feature tests of scriptindex.
917 printf 'uuid : boolean=Q unique=Q\nguid : boolean=G unique=G' > "$TEST_INDEXSCRIPT"
918 rm -rf "$TEST_DB"
919 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null < /dev/null 2>&1; then
920 echo "scriptindex didn't reject 'unique' action being used more than once"
921 failed=`expr $failed + 1`
924 # Test we check for hash's argument being an integer (new in 1.4.6).
925 printf 'url : hash=37.3 boolean=Q unique=Q' > "$TEST_INDEXSCRIPT"
926 rm -rf "$TEST_DB"
927 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
928 | grep -q ":1:14: warning: Index action 'hash' takes an integer argument" ; then
929 : # OK
930 else
931 echo "scriptindex didn't reject 'hash' with a non-integer argument"
932 failed=`expr $failed + 1`
935 # Test we give a helpful error for an action with a digit in (regression
936 # test for fix in 1.4.6).
938 # This used to give the confusing:
939 # Unknown index action ''
940 printf 'url : index4' > "$TEST_INDEXSCRIPT"
941 rm -rf "$TEST_DB"
942 rc=0
943 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
944 if [ $rc -eq 0 ] ; then
945 echo "scriptindex didn't exit with non-zero return code for bad index action with a digit"
946 failed=`expr $failed + 1`
947 elif printf '%s' "$out" \
948 | grep -q ":1:7: error: Unknown index action 'index4'" ; then
949 : # OK
950 else
951 echo "scriptindex didn't give expected error for bad index action with a digit"
952 failed=`expr $failed + 1`
955 # Test we give a helpful error if an = sign is missed out before an optional
956 # numeric argument (regression test for fix in 1.4.6).
958 # This used to give the confusing:
959 # Unknown index action ''
960 printf 'url : hash 42' > "$TEST_INDEXSCRIPT"
961 rm -rf "$TEST_DB"
962 rc=0
963 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
964 if [ $rc -eq 0 ] ; then
965 echo "scriptindex didn't exit with non-zero return code for a missing equals sign"
966 failed=`expr $failed + 1`
967 elif printf '%s' "$out" \
968 | grep -q ":1:12: error: Unknown index action '42'" ; then
969 : # OK
970 else
971 echo "scriptindex didn't give expected error for a missing equals sign"
972 failed=`expr $failed + 1`
975 # Test we warn about spaces before and after '='.
977 # This has never been documented as supported, and was deprecated in 1.4.6
978 # because it resulted in this quietly using hash as the field name, which is
979 # probably not what was intended:
981 # url : field= hash boolean=Q unique=Q
982 printf 'url : field= hash boolean=Q unique=Q' > "$TEST_INDEXSCRIPT"
983 rm -rf "$TEST_DB"
984 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
985 | grep -q ":1:13: warning: putting spaces between '=' and the argument is deprecated" ; then
986 : # OK
987 else
988 echo "scriptindex didn't give expected warning for space after '='"
989 failed=`expr $failed + 1`
991 printf 'url : field =link' > "$TEST_INDEXSCRIPT"
992 rm -rf "$TEST_DB"
993 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
994 | grep -q ":1:12: warning: putting spaces between the action and '=' is deprecated" ; then
995 : # OK
996 else
997 echo "scriptindex didn't give expected warning for space before '='"
998 failed=`expr $failed + 1`
1001 # Feature tests for datevalue command scriptindex.
1002 printf '%s\n' 'DATE : field parsedate=%Y%m%d valuepacked=13' > "$TEST_INDEXSCRIPT"
1003 rm -rf "$TEST_DB"
1004 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
1005 DATE=19891204
1007 printf '$field{DATE,1}|$unpack{$value{13,1}}|$date{$unpack{$value{13,1}}}' > "$TEST_TEMPLATE"
1008 testcase '19891204|628732800|1989-12-04' P=text
1010 # Feature tests for datevalue command scriptindex where format contains space.
1011 printf '%s\n' 'DATE : field parsedate="%Y%m%d %T" valuepacked=13' > "$TEST_INDEXSCRIPT"
1012 rm -rf "$TEST_DB"
1013 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null 2>&1 <<'END'
1014 DATE=20161202 12:04:22.000000
1016 printf '$unpack{$value{13,1}}|$date{$unpack{$value{13,1}}}' > "$TEST_TEMPLATE"
1017 testcase '1480680262|2016-12-02' P=text
1019 # Feature tests for quoted arguments.
1020 printf 'DATE : field=" spaces " date="yyyymmdd"\nTEXT: index\n' > "$TEST_INDEXSCRIPT"
1021 rm -rf "$TEST_DB"
1022 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
1023 DATE=19891204
1024 TEXT=This is sample text.
1025 NEXT=work
1027 printf '$freq{D19891204}|$field{ spaces ,1}' > "$TEST_TEMPLATE"
1028 testcase '1|19891204' P=text
1029 # Use $time to force the match to run.
1030 printf '$if{$time,$freq{D19891204}}|$field{ spaces ,1}' > "$TEST_TEMPLATE"
1031 testcase '1|19891204' P=
1033 # Feature tests for escaping in quoted arguments.
1034 printf '%s\n' 'esc : field="\tesca\x70e,test\\\""' > "$TEST_INDEXSCRIPT"
1035 rm -rf "$TEST_DB"
1036 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
1037 esc=test
1039 printf '$field{$chr{9}escape$.test\\",1}' > "$TEST_TEMPLATE"
1040 testcase 'test' P=
1041 # Ensure the location of the problem is always in the same column so we can
1042 # test against a fixed error message including line and column.
1043 for badesc in \
1044 '"xx\' \
1045 '"xx\q"' \
1046 '"\x"' \
1047 '"\x1"' \
1048 '"\xg"' \
1049 '"\x1g"' \
1050 '"\x1g"' \
1051 ; do
1052 printf '%s' "x: split=$badesc" > "$TEST_INDEXSCRIPT"
1053 rm -rf "$TEST_DB"
1054 rc=0
1055 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
1056 if [ $rc -eq 0 ] ; then
1057 echo "scriptindex didn't exit with non-zero return code on bad escaping"
1058 failed=`expr $failed + 1`
1059 elif printf '%s' "$out" \
1060 | grep -q ":1:14: error: Bad escaping in quoted action argument" ; then
1061 : # OK
1062 else
1063 echo "scriptindex didn't give expected error for bad escaping"
1064 printf '%s\n' "badesc=$badesc" "got: $out"
1065 failed=`expr $failed + 1`
1067 done
1069 # Regression test that a closing " with junk after is flagged.
1070 printf 'date : field="test"index' > "$TEST_INDEXSCRIPT"
1071 rm -rf "$TEST_DB"
1072 rc=0
1073 out=`$SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1` || rc=$?
1074 if [ $rc -eq 0 ] ; then
1075 echo "scriptindex didn't exit with non-zero return code for junk after closing quote"
1076 failed=`expr $failed + 1`
1077 elif printf '%s' "$out" \
1078 | grep -q ":1:20: error: Unexpected character 'i' after closing quote" ; then
1079 : # OK
1080 else
1081 echo "scriptindex didn't give expected error for junk after closing quote"
1082 failed=`expr $failed + 1`
1085 # Test we warn about useless actions.
1086 printf 'date : field parsedate=%%Y%%m%%d' > "$TEST_INDEXSCRIPT"
1087 rm -rf "$TEST_DB"
1088 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null 2>&1 \
1089 | grep -q ":1:14: warning: Index action 'parsedate' has no effect" ; then
1090 : # OK
1091 else
1092 echo "scriptindex didn't give expected warning for useless 'parsedate'"
1093 failed=`expr $failed + 1`
1096 # The 'hash' action should require its argument is >= 6, so test 5 is rejected.
1097 printf 'url : hash=5 boolean=Q unique=Q' > "$TEST_INDEXSCRIPT"
1098 rm -rf "$TEST_DB"
1099 if $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" < /dev/null > /dev/null 2>&1 ; then
1100 echo "scriptindex didn't reject 'hash=5'"
1101 failed=`expr $failed + 1`
1104 # And that 6 is accepted.
1105 printf 'url : hash=6 boolean=Q unique=Q' > "$TEST_INDEXSCRIPT"
1106 rm -rf "$TEST_DB"
1107 if echo 'url=http://xapian.org' | $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null 2>&1 ; then
1108 : # OK
1109 else
1110 echo "scriptindex rejected 'hash=6'"
1111 failed=`expr $failed + 1`
1114 # Regression test to check hash works without argument (it was failing with an
1115 # assertion in unreleased versions prior to 1.4.6).
1116 printf 'url : hash boolean=Q unique=Q' > "$TEST_INDEXSCRIPT"
1117 rm -rf "$TEST_DB"
1118 if echo 'url=http://xapian.org' | $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null 2>&1 ; then
1119 : # OK
1120 else
1121 echo "scriptindex rejected 'hash'"
1122 failed=`expr $failed + 1`
1125 # Test the same actions for multiple fields works (briefly broken in git master
1126 # before 1.5.0).
1127 printf 'tag1 tag2 tag3 : boolean=T field' > "$TEST_INDEXSCRIPT"
1128 rm -rf "$TEST_DB"
1129 $SCRIPTINDEX "$TEST_DB" "$TEST_INDEXSCRIPT" > /dev/null <<'END'
1130 tag1=one
1131 tag2=two
1132 tag3=three
1134 printf '$hitlist{$list{$terms{T},|}/$field{tag1}|$field{tag2}|$field{tag3}}' > "$TEST_TEMPLATE"
1135 testcase 'Tone/one|two|three' B=Tone
1136 testcase 'Tthree|Ttwo/one|two|three' B=Ttwo B=Tthree
1138 rm "$OMEGA_CONFIG_FILE" "$TEST_INDEXSCRIPT" "$TEST_TEMPLATE"
1139 rm -rf "$TEST_DB"
1140 if [ "$failed" = 0 ] ; then
1141 exit 0
1143 echo "Failed $failed test(s)"
1144 exit 1