1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2003 Martin Wille
4 http://spirit.sourceforge.net/
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
12 #include <boost/detail/lightweight_test.hpp>
13 #include <boost/spirit/include/classic_core.hpp>
14 #include <boost/spirit/include/classic_symbols.hpp>
15 #include <boost/detail/lightweight_test.hpp>
16 #include <boost/swap.hpp>
17 #include "symbols.hpp"
19 ///////////////////////////////////////////////////////////////////////////////
21 using namespace BOOST_SPIRIT_CLASSIC_NS
;
23 ///////////////////////////////////////////////////////////////////////////////
25 template <typename IteratorT
>
27 equal(IteratorT p
, IteratorT q
)
29 while (*p
&& *p
== *q
)
37 template <class SymbolsT
, typename CharT
>
42 CharT
const *candidate
,
48 parse_info
<CharT
const*> info
= parse(candidate
, sym
);
50 #define correctly_matched hit == info.hit
51 #define correct_match_length unsigned(length) == info.length
52 #define correct_tail equal(candidate + (hit?1:0)*length, result)
54 BOOST_TEST(correctly_matched
);
58 BOOST_TEST(correct_match_length
);
59 BOOST_TEST(correct_tail
);
63 BOOST_TEST(correct_tail
);
70 store_action(T
const &v
) : value(v
) {}
71 void operator()(T
&v
) const { v
= value
; }
86 check_action(T
const &v
) : value(v
) {}
88 #define correct_value_stored (v==value)
89 void operator()(T
const &v
) const { BOOST_TEST(correct_value_stored
); }
102 default_constructible()
103 { // this actually a compile time test
104 symbols
<int, char, quickbook::tst
<int, char> > ns1
;
105 symbols
<int, wchar_t, quickbook::tst
<int, wchar_t> > ws1
;
106 symbols
<std::string
, char, quickbook::tst
<std::string
, char> > ns2
;
107 symbols
<std::string
, wchar_t, quickbook::tst
<std::string
, wchar_t> > ws2
;
109 (void)ns1
; (void)ws1
; (void)ns2
; (void)ws2
;
112 typedef symbols
<int, char, quickbook::tst
<int, char> > nsymbols
;
113 typedef symbols
<int, wchar_t, quickbook::tst
<int, wchar_t> > wsymbols
;
119 sym
= "pineapple", "orange", "banana", "applepie", "apple";
121 docheck(sym
, "pineapple", true, "", 9);
122 docheck(sym
, "orange", true, "", 6);
123 docheck(sym
, "banana", true, "", 6);
124 docheck(sym
, "apple", true, "", 5);
125 docheck(sym
, "pizza", false, "pizza", -1);
126 docheck(sym
, "steak", false, "steak", -1);
127 docheck(sym
, "applepie", true, "", 8);
128 docheck(sym
, "bananarama", true, "rama", 6);
129 docheck(sym
, "applet", true, "t", 5);
130 docheck(sym
, "applepi", true, "pi", 5);
131 docheck(sym
, "appl", false, "appl", -1);
133 docheck(sym
, "pineapplez", true, "z", 9);
134 docheck(sym
, "orangez", true, "z", 6);
135 docheck(sym
, "bananaz", true, "z", 6);
136 docheck(sym
, "applez", true, "z", 5);
137 docheck(sym
, "pizzaz", false, "pizzaz", -1);
138 docheck(sym
, "steakz", false, "steakz", -1);
139 docheck(sym
, "applepiez", true, "z", 8);
140 docheck(sym
, "bananaramaz", true, "ramaz", 6);
141 docheck(sym
, "appletz", true, "tz", 5);
142 docheck(sym
, "applepix", true, "pix", 5);
146 narrow_copy_ctor_tests()
149 sym
= "pineapple", "orange", "banana", "applepie", "apple";
152 docheck(sym2
, "pineapple", true, "", 9);
153 docheck(sym2
, "pizza", false, "pizza", -1);
154 docheck(sym2
, "bananarama", true, "rama", 6);
158 narrow_assigment_operator_tests()
161 sym
= "pineapple", "orange", "banana", "applepie", "apple";
166 docheck(sym2
, "pineapple", true, "", 9);
167 docheck(sym2
, "pizza", false, "pizza", -1);
168 docheck(sym2
, "bananarama", true, "rama", 6);
175 sym
= "pineapple", "orange", "banana", "applepie", "apple";
176 sym2
= "potato", "cucumber", "cauliflower", "carrot";
178 boost::swap(sym
, sym2
);
180 docheck(sym2
, "pineapple", true, "", 9);
181 docheck(sym2
, "pizza", false, "pizza", -1);
182 docheck(sym2
, "bananarama", true, "rama", 6);
183 docheck(sym
, "potatoe", true, "e", 6);
184 docheck(sym
, "cauliflour", false, "cauliflour", -1);
189 { // also tests the add member functions
192 sym
= "orange", "banana";
193 sym
.add("pineapple",1234);
196 parse("orange", sym
[store(12345)]);
197 parse("orange", sym
[docheck(12345)]);
198 parse("pineapple", sym
[docheck(1234)]);
199 parse("banana", sym
[docheck(int())]);
200 parse("lemon", sym
[docheck(int())]);
204 narrow_free_functions_tests()
208 #define add_returned_non_null_value (res!=0)
209 #define add_returned_null (res==0)
210 #define find_returned_non_null_value (res!=0)
211 #define find_returned_null (res==0)
213 int *res
= add(sym
,"pineapple");
214 BOOST_TEST(add_returned_non_null_value
);
215 res
= add(sym
,"pineapple");
216 BOOST_TEST(add_returned_null
);
218 res
= find(sym
, "pineapple");
219 BOOST_TEST(find_returned_non_null_value
);
220 res
= find(sym
, "banana");
221 BOOST_TEST(find_returned_null
);
228 sym
= L
"pineapple", L
"orange", L
"banana", L
"applepie", L
"apple";
230 docheck(sym
, L
"pineapple", true, L
"", 9);
231 docheck(sym
, L
"orange", true, L
"", 6);
232 docheck(sym
, L
"banana", true, L
"", 6);
233 docheck(sym
, L
"apple", true, L
"", 5);
234 docheck(sym
, L
"pizza", false, L
"pizza", -1);
235 docheck(sym
, L
"steak", false, L
"steak", -1);
236 docheck(sym
, L
"applepie", true, L
"", 8);
237 docheck(sym
, L
"bananarama", true, L
"rama", 6);
238 docheck(sym
, L
"applet", true, L
"t", 5);
239 docheck(sym
, L
"applepi", true, L
"pi", 5);
240 docheck(sym
, L
"appl", false, L
"appl", -1);
242 docheck(sym
, L
"pineapplez", true, L
"z", 9);
243 docheck(sym
, L
"orangez", true, L
"z", 6);
244 docheck(sym
, L
"bananaz", true, L
"z", 6);
245 docheck(sym
, L
"applez", true, L
"z", 5);
246 docheck(sym
, L
"pizzaz", false, L
"pizzaz", -1);
247 docheck(sym
, L
"steakz", false, L
"steakz", -1);
248 docheck(sym
, L
"applepiez", true, L
"z", 8);
249 docheck(sym
, L
"bananaramaz", true, L
"ramaz", 6);
250 docheck(sym
, L
"appletz", true, L
"tz", 5);
251 docheck(sym
, L
"applepix", true, L
"pix", 5);
255 wide_copy_ctor_tests()
258 sym
= L
"pineapple", L
"orange", L
"banana", L
"applepie", L
"apple";
261 docheck(sym2
, L
"pineapple", true, L
"", 9);
262 docheck(sym2
, L
"pizza", false, L
"pizza", -1);
263 docheck(sym2
, L
"bananarama", true, L
"rama", 6);
267 wide_assigment_operator_tests()
270 sym
= L
"pineapple", L
"orange", L
"banana", L
"applepie", L
"apple";
275 docheck(sym2
, L
"pineapple", true, L
"", 9);
276 docheck(sym2
, L
"pizza", false, L
"pizza", -1);
277 docheck(sym2
, L
"bananarama", true, L
"rama", 6);
284 sym
= L
"pineapple", L
"orange", L
"banana", L
"applepie", L
"apple";
285 sym2
= L
"potato", L
"cucumber", L
"cauliflower", L
"carrot";
287 boost::swap(sym
, sym2
);
289 docheck(sym2
, L
"pineapple", true, L
"", 9);
290 docheck(sym2
, L
"pizza", false, L
"pizza", -1);
291 docheck(sym2
, L
"bananarama", true, L
"rama", 6);
292 docheck(sym
, L
"potatoe", true, L
"e", 6);
293 docheck(sym
, L
"cauliflour", false, L
"cauliflour", -1);
298 { // also tests the add member functions
301 sym
= L
"orange", L
"banana";
302 sym
.add(L
"pineapple",1234);
305 parse(L
"orange", sym
[store(12345)]);
306 parse(L
"orange", sym
[docheck(12345)]);
307 parse(L
"pineapple", sym
[docheck(1234)]);
308 parse(L
"banana", sym
[docheck(int())]);
309 parse(L
"lemon", sym
[docheck(int())]);
313 wide_free_functions_tests()
317 int *res
= add(sym
,L
"pineapple");
318 BOOST_TEST(add_returned_non_null_value
);
319 res
= add(sym
,L
"pineapple");
320 BOOST_TEST(add_returned_null
);
322 res
= find(sym
, L
"pineapple");
323 BOOST_TEST(find_returned_non_null_value
);
324 res
= find(sym
, L
"banana");
325 BOOST_TEST(find_returned_null
);
329 void free_add_find_functions_tests()
332 BOOST_TEST(*add(sym
, "a", 0) == 0);
333 BOOST_TEST(*add(sym
, "a2", 1) == 1);
334 BOOST_TEST(add(sym
, "a2", 2) == 0);
335 BOOST_TEST(find(sym
, "a2"));
336 BOOST_TEST(find(sym
, "a"));
339 // The original teneray search tree implementation contained a bug when
340 // inserting duplicate values. I want this implementation to be as
341 // close as possible to the original (so they can be easily switched)
342 // so check that the bug remains the same.
344 struct check_parse_value
346 explicit check_parse_value(int value
) : value_(value
){}
348 void operator()(int value
) const { BOOST_TEST(value
== value_
); }
353 // My version is different to the original, if there's an existing value
354 // it replaces it with the new one.
357 void duplicate_add_tests()
359 char const* foo1
= "foo";
360 char const* foo2
= foo1
+ 3;
363 sym
.add(foo1
, foo2
, 1);
365 sym
.add(foo1
, foo2
, 2);
366 sym2
.add(foo1
, foo2
, 3);
368 BOOST_TEST(find(sym
, "foo") && *find(sym
, "foo") == 2);
369 BOOST_TEST(find(sym2
, "foo") && *find(sym2
, "foo") == 3);
371 parse_info
<char const*> info
;
373 info
= parse("foo ", sym
[check_parse_value(2)]);
374 BOOST_TEST(info
.hit
&& info
.length
== 3);
376 info
= parse("foo", sym
[check_parse_value(2)]);
377 BOOST_TEST(info
.hit
&& info
.length
== 3);
379 info
= parse("foo ", sym2
[check_parse_value(3)]);
380 BOOST_TEST(info
.hit
&& info
.length
== 3);
382 info
= parse("foo", sym2
[check_parse_value(3)]);
383 BOOST_TEST(info
.hit
&& info
.length
== 3);
389 default_constructible();
390 narrow_match_tests();
391 narrow_copy_ctor_tests();
392 narrow_assigment_operator_tests();
394 narrow_value_tests();
395 narrow_free_functions_tests();
397 wide_copy_ctor_tests();
398 wide_assigment_operator_tests();
401 wide_free_functions_tests();
402 free_add_find_functions_tests();
403 duplicate_add_tests();
405 return boost::report_errors();