Branch data Line data Source code
1 : : /** @file api_qpbackend.cc
2 : : * @brief QueryParser tests which need a backend
3 : : */
4 : : /* Copyright (c) 2009 Olly Betts
5 : : *
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.
10 : : *
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.
15 : : *
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 : : */
21 : :
22 : : #include <config.h>
23 : :
24 : : #include "api_qpbackend.h"
25 : :
26 : : #include <xapian.h>
27 : :
28 : : #include "backendmanager.h"
29 : : #include "testsuite.h"
30 : : #include "testutils.h"
31 : :
32 : : #include "apitest.h"
33 : :
34 : : using namespace std;
35 : :
36 : : struct test {
37 : : const char *query;
38 : : const char *expect;
39 : : };
40 : :
41 : : /// Regression test for bug#407 fixed in 1.0.17 and 1.1.3.
42 : 3 : DEFINE_TESTCASE(qpsynonympartial1, synonyms) {
43 : : static const test test_queries[] = {
44 : : { "hello", "hello:(pos=1)" },
45 : : { "~hello", "(hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1))" },
46 : : { "hello world", "(hello:(pos=1) OR world:(pos=2))" },
47 : : { "~hello world", "((hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1)) OR world:(pos=2))" },
48 : : { "world ~hello", "(world:(pos=1) OR (hello:(pos=2) SYNONYM hi:(pos=2) SYNONYM howdy:(pos=2)))" },
49 : : { NULL, NULL }
50 : : };
51 : : static const test test_queries_auto[] = {
52 : : { "hello", "(hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1))" },
53 : : { "~hello", "(hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1))" },
54 : : { "hello world", "((hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1)) OR world:(pos=2))" },
55 : : { "~hello world", "((hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1)) OR world:(pos=2))" },
56 : : { "world ~hello", "(world:(pos=1) OR (hello:(pos=2) SYNONYM hi:(pos=2) SYNONYM howdy:(pos=2)))" },
57 : : { NULL, NULL }
58 : : };
59 : : static const test test_queries_partial_auto[] = {
60 : : { "hello", "hello:(pos=1)" },
61 : : { "~hello", "hello:(pos=1)" },
62 : : { "hello world", "((hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1)) OR world:(pos=2))" },
63 : : { "~hello world", "((hello:(pos=1) SYNONYM hi:(pos=1) SYNONYM howdy:(pos=1)) OR world:(pos=2))" },
64 : : { "world ~hello", "(world:(pos=1) OR hello:(pos=2))" },
65 : : { NULL, NULL }
66 : : };
67 : :
68 : 3 : Xapian::WritableDatabase db(get_writable_database());
69 : 3 : db.add_synonym("hello", "hi");
70 : 3 : db.add_synonym("hello", "howdy");
71 : 3 : db.commit();
72 : :
73 : 3 : Xapian::Enquire enquire(db);
74 : 3 : Xapian::QueryParser qp;
75 : 3 : Xapian::Stem stemmmer("english");
76 : 3 : qp.set_database(db);
77 : 3 : qp.add_prefix("foo", "XFOO");
78 : :
79 : : const test *p;
80 [ + + ]: 18 : for (p = test_queries; p->query; ++p) {
81 : 15 : string expect, parsed;
82 [ + - ]: 15 : if (p->expect)
83 : 15 : expect = p->expect;
84 : : else
85 : 0 : expect = "parse error";
86 : : try {
87 : 15 : unsigned f = qp.FLAG_SYNONYM | qp.FLAG_PARTIAL | qp.FLAG_DEFAULT;
88 : 15 : Xapian::Query qobj = qp.parse_query(p->query, f);
89 : 15 : parsed = qobj.get_description();
90 : 15 : expect = string("Xapian::Query(") + expect + ')';
91 : 0 : } catch (const Xapian::QueryParserError &e) {
92 : 0 : parsed = e.get_msg();
93 : 0 : } catch (const Xapian::Error &e) {
94 : 0 : parsed = e.get_description();
95 : 0 : } catch (...) {
96 : 0 : parsed = "Unknown exception!";
97 : : }
98 : 15 : tout << "Query: " << p->query << '\n';
99 [ - + # # ]: 15 : TEST_STRINGS_EQUAL(parsed, expect);
100 : : }
101 : :
102 [ + + ]: 18 : for (p = test_queries_auto; p->query; ++p) {
103 : 15 : string expect, parsed;
104 [ + - ]: 15 : if (p->expect)
105 : 15 : expect = p->expect;
106 : : else
107 : 0 : expect = "parse error";
108 : : try {
109 : 15 : unsigned f = qp.FLAG_AUTO_SYNONYMS | qp.FLAG_DEFAULT;
110 : 15 : Xapian::Query qobj = qp.parse_query(p->query, f);
111 : 15 : parsed = qobj.get_description();
112 : 15 : expect = string("Xapian::Query(") + expect + ')';
113 : 0 : } catch (const Xapian::QueryParserError &e) {
114 : 0 : parsed = e.get_msg();
115 : 0 : } catch (const Xapian::Error &e) {
116 : 0 : parsed = e.get_description();
117 : 0 : } catch (...) {
118 : 0 : parsed = "Unknown exception!";
119 : : }
120 : 15 : tout << "Query: " << p->query << '\n';
121 [ - + # # ]: 15 : TEST_STRINGS_EQUAL(parsed, expect);
122 : : }
123 : :
124 [ + + ]: 18 : for (p = test_queries_partial_auto; p->query; ++p) {
125 : 15 : string expect, parsed;
126 [ + - ]: 15 : if (p->expect)
127 : 15 : expect = p->expect;
128 : : else
129 : 0 : expect = "parse error";
130 : : try {
131 : 15 : unsigned f = qp.FLAG_AUTO_SYNONYMS | qp.FLAG_PARTIAL;
132 : 15 : f |= qp.FLAG_DEFAULT;
133 : 15 : Xapian::Query qobj = qp.parse_query(p->query, f);
134 : 15 : parsed = qobj.get_description();
135 : 15 : expect = string("Xapian::Query(") + expect + ')';
136 : 0 : } catch (const Xapian::QueryParserError &e) {
137 : 0 : parsed = e.get_msg();
138 : 0 : } catch (const Xapian::Error &e) {
139 : 0 : parsed = e.get_description();
140 : 0 : } catch (...) {
141 : 0 : parsed = "Unknown exception!";
142 : : }
143 : 15 : tout << "Query: " << p->query << '\n';
144 [ - + # # ]: 15 : TEST_STRINGS_EQUAL(parsed, expect);
145 : : }
146 : :
147 : 3 : return true;
148 : : }
|