1 /*=============================================================================
2 Copyright (c) 2001-2015 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include <boost/detail/lightweight_test.hpp>
8 #include <boost/spirit/home/x3/string/tst.hpp>
9 #include <boost/spirit/home/x3/string/tst_map.hpp>
10 #include <boost/spirit/home/x3/support/no_case.hpp>
11 #include <boost/spirit/home/support/char_encoding/standard.hpp>
12 #include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
13 #include <string>
14 #include <cctype>
15 #include <iostream>
16
17 namespace
18 {
19 template <typename TST, typename Char>
add(TST & tst,Char const * s,int data)20 void add(TST& tst, Char const* s, int data)
21 {
22 Char const* last = s;
23 while (*last)
24 last++;
25 tst.add(s, last, data);
26 }
27
28 template <typename TST, typename Char>
remove(TST & tst,Char const * s)29 void remove(TST& tst, Char const* s)
30 {
31 Char const* last = s;
32 while (*last)
33 last++;
34 tst.remove(s, last);
35 }
36
37 template <typename TST, typename Char, typename CaseCompare>
docheck(TST const & tst,CaseCompare const & comp,Char const * s,bool expected,int N=0,int val=-1)38 void docheck(TST const& tst, CaseCompare const& comp, Char const* s, bool expected, int N = 0, int val = -1)
39 {
40 Char const* first = s;
41 Char const* last = s;
42 while (*last)
43 last++;
44 int* r = tst.find(s, last,comp);
45 BOOST_TEST((r != 0) == expected);
46 if (r != 0)
47 BOOST_TEST((s-first) == N);
48 if (r)
49 BOOST_TEST(*r == val);
50 }
51
52 struct printer
53 {
54 template <typename String, typename Data>
operator ()__anon80aef55a0111::printer55 void operator()(String const& s, Data const& data)
56 {
57 std::cout << " " << s << ": " << data << std::endl;
58 }
59 };
60
61 template <typename TST>
print(TST const & tst)62 void print(TST const& tst)
63 {
64 std::cout << '[' << std::endl;
65 tst.for_each(printer());
66 std::cout << ']' << std::endl;
67 }
68
69 }
70
71 boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard> ncomp;
72 boost::spirit::x3::case_compare<boost::spirit::char_encoding::standard_wide> wcomp;
73 boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard> nc_ncomp;
74 boost::spirit::x3::no_case_compare<boost::spirit::char_encoding::standard_wide> nc_wcomp;
75
76 template <typename Lookup, typename WideLookup>
tests()77 void tests()
78 {
79 { // basic tests
80 Lookup lookup;
81
82 docheck(lookup, ncomp, "not-yet-there", false);
83 docheck(lookup, ncomp, "", false);
84
85 add(lookup, "apple", 123);
86 docheck(lookup, ncomp, "apple", true, 5, 123); // full match
87 docheck(lookup, ncomp, "banana", false); // no-match
88 docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
89
90 add(lookup, "applepie", 456);
91 docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
92 docheck(lookup, ncomp, "banana", false); // no-match
93 docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
94 docheck(lookup, ncomp, "apple", true, 5, 123); // full match
95 docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
96 }
97
98 { // variation of above
99 Lookup lookup;
100
101 add(lookup, "applepie", 456);
102 add(lookup, "apple", 123);
103
104 docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
105 docheck(lookup, ncomp, "banana", false); // no-match
106 docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
107 docheck(lookup, ncomp, "apple", true, 5, 123); // full match
108 docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
109 }
110 { // variation of above
111 Lookup lookup;
112
113 add(lookup, "applepie", 456);
114 add(lookup, "apple", 123);
115
116 docheck(lookup, ncomp, "applepie", true, 8, 456); // full match
117 docheck(lookup, ncomp, "banana", false); // no-match
118 docheck(lookup, ncomp, "applepiexxx", true, 8, 456); // partial match
119 docheck(lookup, ncomp, "apple", true, 5, 123); // full match
120 docheck(lookup, ncomp, "applexxx", true, 5, 123); // partial match
121 }
122
123 { // narrow char tests
124 Lookup lookup;
125 add(lookup, "pineapple", 1);
126 add(lookup, "orange", 2);
127 add(lookup, "banana", 3);
128 add(lookup, "applepie", 4);
129 add(lookup, "apple", 5);
130
131 docheck(lookup, ncomp, "pineapple", true, 9, 1);
132 docheck(lookup, ncomp, "orange", true, 6, 2);
133 docheck(lookup, ncomp, "banana", true, 6, 3);
134 docheck(lookup, ncomp, "apple", true, 5, 5);
135 docheck(lookup, ncomp, "pizza", false);
136 docheck(lookup, ncomp, "steak", false);
137 docheck(lookup, ncomp, "applepie", true, 8, 4);
138 docheck(lookup, ncomp, "bananarama", true, 6, 3);
139 docheck(lookup, ncomp, "applet", true, 5, 5);
140 docheck(lookup, ncomp, "applepi", true, 5, 5);
141 docheck(lookup, ncomp, "appl", false);
142
143 docheck(lookup, ncomp, "pineapplez", true, 9, 1);
144 docheck(lookup, ncomp, "orangez", true, 6, 2);
145 docheck(lookup, ncomp, "bananaz", true, 6, 3);
146 docheck(lookup, ncomp, "applez", true, 5, 5);
147 docheck(lookup, ncomp, "pizzaz", false);
148 docheck(lookup, ncomp, "steakz", false);
149 docheck(lookup, ncomp, "applepiez", true, 8, 4);
150 docheck(lookup, ncomp, "bananaramaz", true, 6, 3);
151 docheck(lookup, ncomp, "appletz", true, 5, 5);
152 docheck(lookup, ncomp, "applepix", true, 5, 5);
153 }
154
155 { // wide char tests
156 WideLookup lookup;
157 add(lookup, L"pineapple", 1);
158 add(lookup, L"orange", 2);
159 add(lookup, L"banana", 3);
160 add(lookup, L"applepie", 4);
161 add(lookup, L"apple", 5);
162
163 docheck(lookup, wcomp, L"pineapple", true, 9, 1);
164 docheck(lookup, wcomp, L"orange", true, 6, 2);
165 docheck(lookup, wcomp, L"banana", true, 6, 3);
166 docheck(lookup, wcomp, L"apple", true, 5, 5);
167 docheck(lookup, wcomp, L"pizza", false);
168 docheck(lookup, wcomp, L"steak", false);
169 docheck(lookup, wcomp, L"applepie", true, 8, 4);
170 docheck(lookup, wcomp, L"bananarama", true, 6, 3);
171 docheck(lookup, wcomp, L"applet", true, 5, 5);
172 docheck(lookup, wcomp, L"applepi", true, 5, 5);
173 docheck(lookup, wcomp, L"appl", false);
174
175 docheck(lookup, wcomp, L"pineapplez", true, 9, 1);
176 docheck(lookup, wcomp, L"orangez", true, 6, 2);
177 docheck(lookup, wcomp, L"bananaz", true, 6, 3);
178 docheck(lookup, wcomp, L"applez", true, 5, 5);
179 docheck(lookup, wcomp, L"pizzaz", false);
180 docheck(lookup, wcomp, L"steakz", false);
181 docheck(lookup, wcomp, L"applepiez", true, 8, 4);
182 docheck(lookup, wcomp, L"bananaramaz", true, 6, 3);
183 docheck(lookup, wcomp, L"appletz", true, 5, 5);
184 docheck(lookup, wcomp, L"applepix", true, 5, 5);
185 }
186
187 { // test remove
188 Lookup lookup;
189 add(lookup, "pineapple", 1);
190 add(lookup, "orange", 2);
191 add(lookup, "banana", 3);
192 add(lookup, "applepie", 4);
193 add(lookup, "apple", 5);
194
195 docheck(lookup, ncomp, "pineapple", true, 9, 1);
196 docheck(lookup, ncomp, "orange", true, 6, 2);
197 docheck(lookup, ncomp, "banana", true, 6, 3);
198 docheck(lookup, ncomp, "apple", true, 5, 5);
199 docheck(lookup, ncomp, "applepie", true, 8, 4);
200 docheck(lookup, ncomp, "bananarama", true, 6, 3);
201 docheck(lookup, ncomp, "applet", true, 5, 5);
202 docheck(lookup, ncomp, "applepi", true, 5, 5);
203 docheck(lookup, ncomp, "appl", false);
204
205 remove(lookup, "banana");
206 docheck(lookup, ncomp, "pineapple", true, 9, 1);
207 docheck(lookup, ncomp, "orange", true, 6, 2);
208 docheck(lookup, ncomp, "banana", false);
209 docheck(lookup, ncomp, "apple", true, 5, 5);
210 docheck(lookup, ncomp, "applepie", true, 8, 4);
211 docheck(lookup, ncomp, "bananarama", false);
212 docheck(lookup, ncomp, "applet", true, 5, 5);
213 docheck(lookup, ncomp, "applepi", true, 5, 5);
214 docheck(lookup, ncomp, "appl", false);
215
216 remove(lookup, "apple");
217 docheck(lookup, ncomp, "pineapple", true, 9, 1);
218 docheck(lookup, ncomp, "orange", true, 6, 2);
219 docheck(lookup, ncomp, "apple", false);
220 docheck(lookup, ncomp, "applepie", true, 8, 4);
221 docheck(lookup, ncomp, "applet", false);
222 docheck(lookup, ncomp, "applepi", false);
223 docheck(lookup, ncomp, "appl", false);
224
225 remove(lookup, "orange");
226 docheck(lookup, ncomp, "pineapple", true, 9, 1);
227 docheck(lookup, ncomp, "orange", false);
228 docheck(lookup, ncomp, "applepie", true, 8, 4);
229
230 remove(lookup, "pineapple");
231 docheck(lookup, ncomp, "pineapple", false);
232 docheck(lookup, ncomp, "orange", false);
233 docheck(lookup, ncomp, "applepie", true, 8, 4);
234
235 remove(lookup, "applepie");
236 docheck(lookup, ncomp, "applepie", false);
237 }
238
239 { // copy/assign/clear test
240 Lookup lookupa;
241 add(lookupa, "pineapple", 1);
242 add(lookupa, "orange", 2);
243 add(lookupa, "banana", 3);
244 add(lookupa, "applepie", 4);
245 add(lookupa, "apple", 5);
246
247 Lookup lookupb(lookupa); // copy ctor
248 docheck(lookupb, ncomp, "pineapple", true, 9, 1);
249 docheck(lookupb, ncomp, "orange", true, 6, 2);
250 docheck(lookupb, ncomp, "banana", true, 6, 3);
251 docheck(lookupb, ncomp, "apple", true, 5, 5);
252 docheck(lookupb, ncomp, "pizza", false);
253 docheck(lookupb, ncomp, "steak", false);
254 docheck(lookupb, ncomp, "applepie", true, 8, 4);
255 docheck(lookupb, ncomp, "bananarama", true, 6, 3);
256 docheck(lookupb, ncomp, "applet", true, 5, 5);
257 docheck(lookupb, ncomp, "applepi", true, 5, 5);
258 docheck(lookupb, ncomp, "appl", false);
259
260 lookupb.clear(); // clear
261 docheck(lookupb, ncomp, "pineapple", false);
262 docheck(lookupb, ncomp, "orange", false);
263 docheck(lookupb, ncomp, "banana", false);
264 docheck(lookupb, ncomp, "apple", false);
265 docheck(lookupb, ncomp, "applepie", false);
266 docheck(lookupb, ncomp, "bananarama", false);
267 docheck(lookupb, ncomp, "applet", false);
268 docheck(lookupb, ncomp, "applepi", false);
269 docheck(lookupb, ncomp, "appl", false);
270
271 lookupb = lookupa; // assign
272 docheck(lookupb, ncomp, "pineapple", true, 9, 1);
273 docheck(lookupb, ncomp, "orange", true, 6, 2);
274 docheck(lookupb, ncomp, "banana", true, 6, 3);
275 docheck(lookupb, ncomp, "apple", true, 5, 5);
276 docheck(lookupb, ncomp, "pizza", false);
277 docheck(lookupb, ncomp, "steak", false);
278 docheck(lookupb, ncomp, "applepie", true, 8, 4);
279 docheck(lookupb, ncomp, "bananarama", true, 6, 3);
280 docheck(lookupb, ncomp, "applet", true, 5, 5);
281 docheck(lookupb, ncomp, "applepi", true, 5, 5);
282 docheck(lookupb, ncomp, "appl", false);
283 }
284
285 { // test for_each
286 Lookup lookup;
287 add(lookup, "pineapple", 1);
288 add(lookup, "orange", 2);
289 add(lookup, "banana", 3);
290 add(lookup, "applepie", 4);
291 add(lookup, "apple", 5);
292
293 print(lookup);
294 }
295
296 { // case insensitive tests
297 Lookup lookup;
298
299 // NOTE: make sure all entries are in lower-case!!!
300 add(lookup, "pineapple", 1);
301 add(lookup, "orange", 2);
302 add(lookup, "banana", 3);
303 add(lookup, "applepie", 4);
304 add(lookup, "apple", 5);
305
306 docheck(lookup, nc_ncomp, "pineapple", true, 9, 1);
307 docheck(lookup, nc_ncomp, "orange", true, 6, 2);
308 docheck(lookup, nc_ncomp, "banana", true, 6, 3);
309 docheck(lookup, nc_ncomp, "apple", true, 5, 5);
310 docheck(lookup, nc_ncomp, "applepie", true, 8, 4);
311
312 docheck(lookup, nc_ncomp, "PINEAPPLE", true, 9, 1);
313 docheck(lookup, nc_ncomp, "ORANGE", true, 6, 2);
314 docheck(lookup, nc_ncomp, "BANANA", true, 6, 3);
315 docheck(lookup, nc_ncomp, "APPLE", true, 5, 5);
316 docheck(lookup, nc_ncomp, "APPLEPIE", true, 8, 4);
317
318 docheck(lookup, nc_ncomp, "pineApple", true, 9, 1);
319 docheck(lookup, nc_ncomp, "orangE", true, 6, 2);
320 docheck(lookup, nc_ncomp, "Banana", true, 6, 3);
321 docheck(lookup, nc_ncomp, "aPPLe", true, 5, 5);
322 docheck(lookup, nc_ncomp, "ApplePie", true, 8, 4);
323
324 print(lookup);
325 }
326 }
327
main()328 int main()
329 {
330 using boost::spirit::x3::tst;
331 using boost::spirit::x3::tst_map;
332
333 tests<tst<char, int>, tst<wchar_t, int> >();
334 //~ tests<tst_map<char, int>, tst_map<wchar_t, int> >();
335
336 return boost::report_errors();
337 }
338