1 | // (C) Copyright Jonathan Turkanis 2005. |
---|
2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
---|
3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) |
---|
4 | |
---|
5 | // See http://www.boost.org/libs/iostreams for documentation. |
---|
6 | |
---|
7 | #include <map> |
---|
8 | #include <boost/iostreams/detail/ios.hpp> // failure. |
---|
9 | #include <boost/iostreams/device/file.hpp> |
---|
10 | #include <boost/iostreams/filter/test.hpp> |
---|
11 | #include <boost/iostreams/stream.hpp> |
---|
12 | #include <boost/mpl/vector.hpp> |
---|
13 | #include <boost/test/test_tools.hpp> |
---|
14 | #include <boost/test/unit_test.hpp> |
---|
15 | #include "../example/container_device.hpp" |
---|
16 | #include "../example/dictionary_filter.hpp" |
---|
17 | #include "../example/line_wrapping_filter.hpp" |
---|
18 | #include "../example/shell_comments_filter.hpp" |
---|
19 | #include "../example/tab_expanding_filter.hpp" |
---|
20 | #include "../example/unix2dos_filter.hpp" |
---|
21 | #include "./detail/verification.hpp" |
---|
22 | #include "./detail/sequence.hpp" |
---|
23 | #include "./detail/temp_file.hpp" |
---|
24 | |
---|
25 | using boost::unit_test::test_suite; |
---|
26 | namespace io = boost::iostreams; |
---|
27 | namespace ex = boost::iostreams::example; |
---|
28 | |
---|
29 | //------------------container_device test-------------------------------------// |
---|
30 | |
---|
31 | void container_device_test() |
---|
32 | { |
---|
33 | using namespace std; |
---|
34 | using namespace boost::iostreams::test; |
---|
35 | |
---|
36 | typedef vector<char> vector_type; |
---|
37 | typedef ex::container_source<vector_type> vector_source; |
---|
38 | typedef ex::container_sink<vector_type> vector_sink; |
---|
39 | typedef ex::container_device<vector_type> vector_device; |
---|
40 | |
---|
41 | { |
---|
42 | test_sequence<> seq; |
---|
43 | test_file file; |
---|
44 | io::stream<vector_source> first(seq); |
---|
45 | io::stream<io::file_source> second(file.name(), in_mode); |
---|
46 | BOOST_CHECK(compare_streams_in_chunks(first, second)); |
---|
47 | } |
---|
48 | |
---|
49 | { |
---|
50 | std::vector<char> first; |
---|
51 | test_sequence<> second; |
---|
52 | io::stream<vector_sink> out(first); |
---|
53 | write_data_in_chunks(out); |
---|
54 | BOOST_CHECK(first == second); |
---|
55 | } |
---|
56 | |
---|
57 | { |
---|
58 | vector<char> v; |
---|
59 | io::stream<vector_device> io(v); |
---|
60 | BOOST_CHECK(test_seekable_in_chunks(io)); |
---|
61 | } |
---|
62 | } |
---|
63 | |
---|
64 | //------------------dictionary_filter test------------------------------------// |
---|
65 | |
---|
66 | void dictionary_filter_test() |
---|
67 | { |
---|
68 | using namespace std; |
---|
69 | |
---|
70 | io::example::dictionary d; |
---|
71 | |
---|
72 | // See http://english2american.com. |
---|
73 | d.add("answerphone", "answering machine"); |
---|
74 | d.add("bloke", "guy"); |
---|
75 | d.add("gearbox", "transmission"); |
---|
76 | d.add("ironmonger", "hardware shop"); |
---|
77 | d.add("loo", "restroom"); |
---|
78 | d.add("lorry", "truck"); |
---|
79 | d.add("rubber", "eraser"); |
---|
80 | d.add("spanner", "monkey wrench"); |
---|
81 | d.add("telly", "TV"); |
---|
82 | d.add("tyre", "tire"); |
---|
83 | d.add("waistcoat", "vest"); |
---|
84 | d.add("windscreen", "windshield"); |
---|
85 | |
---|
86 | const std::string input = // Note: last character is non-alphabetic. |
---|
87 | "I had a message on my answerphone from the bloke at the car " |
---|
88 | "dealership that the windscreen and tyre on my lorry were replaced. " |
---|
89 | "However, the gearbox would not be ready until tomorrow since the " |
---|
90 | "spanner that they needed was broken and they had to go to the " |
---|
91 | "ironmonger to buy a replacement. Since my lorry was not ready, " |
---|
92 | "I decided to take the bus downtown and buy a new waistcoat. I " |
---|
93 | "also stopped at the liquor store to buy some wine. I came home " |
---|
94 | "and watched the telly and drank my wine. I also worked on a " |
---|
95 | "crossword puzzle. Fortunately I had a pencil with a new rubber. " |
---|
96 | "During that evening I made frequent trips to the loo due to my " |
---|
97 | "excessive drinking"; |
---|
98 | |
---|
99 | const std::string output = // Note: last character is non-alphabetic. |
---|
100 | "I had a message on my answering machine from the guy at the car " |
---|
101 | "dealership that the windshield and tire on my truck were replaced. " |
---|
102 | "However, the transmission would not be ready until tomorrow since " |
---|
103 | "the monkey wrench that they needed was broken and they had to go to " |
---|
104 | "the hardware shop to buy a replacement. Since my truck was not ready, " |
---|
105 | "I decided to take the bus downtown and buy a new vest. I also stopped " |
---|
106 | "at the liquor store to buy some wine. I came home and watched the TV " |
---|
107 | "and drank my wine. I also worked on a crossword puzzle. Fortunately I " |
---|
108 | "had a pencil with a new eraser. During that evening I made frequent " |
---|
109 | "trips to the restroom due to my excessive drinking"; |
---|
110 | |
---|
111 | BOOST_CHECK( |
---|
112 | io::test_input_filter( io::example::dictionary_stdio_filter(d), |
---|
113 | input, output ) |
---|
114 | ); |
---|
115 | |
---|
116 | BOOST_CHECK( |
---|
117 | io::test_output_filter( io::example::dictionary_stdio_filter(d), |
---|
118 | input, output ) |
---|
119 | ); |
---|
120 | |
---|
121 | BOOST_CHECK( |
---|
122 | io::test_input_filter( io::example::dictionary_input_filter(d), |
---|
123 | input, output ) |
---|
124 | ); |
---|
125 | |
---|
126 | BOOST_CHECK( |
---|
127 | io::test_output_filter( io::example::dictionary_output_filter(d), |
---|
128 | input, output ) |
---|
129 | ); |
---|
130 | } |
---|
131 | |
---|
132 | //------------------line_wrapping_filter test---------------------------------// |
---|
133 | |
---|
134 | void line_wrapping_filter_test() |
---|
135 | { |
---|
136 | using namespace std; |
---|
137 | |
---|
138 | const std::string input = |
---|
139 | "I had a message on my answerphone from the bloke at the car \n" |
---|
140 | "dealership that the windscreen and tyre on my lorry were replaced. \n" |
---|
141 | "However, the gearbox would not be ready until tomorrow since the \n" |
---|
142 | "spanner that they needed was broken and they had to go to the \n" |
---|
143 | "ironmonger to buy a replacement. Since my lorry was not ready, \n" |
---|
144 | "I decided to take the bus downtown and buy a new waistcoat. I \n" |
---|
145 | "also stopped at the liquor store to buy some wine. I came home \n" |
---|
146 | "and watched the telly and drank my wine. I also worked on a \n" |
---|
147 | "crossword puzzle. Fortunately I had a pencil with a new rubber. \n" |
---|
148 | "During that evening I made frequent trips to the loo due to my \n" |
---|
149 | "excessive drinking."; |
---|
150 | |
---|
151 | const std::string output = |
---|
152 | "I had a message on my answerphone from t\n" |
---|
153 | "he bloke at the car \n" |
---|
154 | "dealership that the windscreen and tyre \n" |
---|
155 | "on my lorry were replaced. \n" |
---|
156 | "However, the gearbox would not be ready \n" |
---|
157 | "until tomorrow since the \n" |
---|
158 | "spanner that they needed was broken and \n" |
---|
159 | "they had to go to the \n" |
---|
160 | "ironmonger to buy a replacement. Since m\n" |
---|
161 | "y lorry was not ready, \n" |
---|
162 | "I decided to take the bus downtown and b\n" |
---|
163 | "uy a new waistcoat. I \n" |
---|
164 | "also stopped at the liquor store to buy \n" |
---|
165 | "some wine. I came home \n" |
---|
166 | "and watched the telly and drank my wine.\n" |
---|
167 | " I also worked on a \n" |
---|
168 | "crossword puzzle. Fortunately I had a pe\n" |
---|
169 | "ncil with a new rubber. \n" |
---|
170 | "During that evening I made frequent trip\n" |
---|
171 | "s to the loo due to my \n" |
---|
172 | "excessive drinking."; |
---|
173 | |
---|
174 | BOOST_CHECK( |
---|
175 | io::test_input_filter( io::example::line_wrapping_stdio_filter(40), |
---|
176 | input, output ) |
---|
177 | ); |
---|
178 | |
---|
179 | BOOST_CHECK( |
---|
180 | io::test_output_filter( io::example::line_wrapping_stdio_filter(40), |
---|
181 | input, output ) |
---|
182 | ); |
---|
183 | |
---|
184 | BOOST_CHECK( |
---|
185 | io::test_input_filter( io::example::line_wrapping_input_filter(40), |
---|
186 | input, output ) |
---|
187 | ); |
---|
188 | |
---|
189 | BOOST_CHECK( |
---|
190 | io::test_output_filter( io::example::line_wrapping_output_filter(40), |
---|
191 | input, output ) |
---|
192 | ); |
---|
193 | } |
---|
194 | |
---|
195 | //------------------shell_comments_filter test--------------------------------// |
---|
196 | |
---|
197 | void shell_comments_filter_test() |
---|
198 | { |
---|
199 | using namespace std; |
---|
200 | |
---|
201 | const std::string input = // From <libs/filesystem/build/Jamfile>. |
---|
202 | "lib boost_filesystem\n" |
---|
203 | " : ../src/$(SOURCES).cpp\n" |
---|
204 | " : # build requirements\n" |
---|
205 | " [ common-names ] # magic for install and auto-link features\n" |
---|
206 | " <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT)\n" |
---|
207 | " <no-warn>exception.cpp <no-warn>operations_posix_windows.cpp\n" |
---|
208 | " : debug release # build variants\n" |
---|
209 | " ;\n" |
---|
210 | "\n" |
---|
211 | "dll boost_filesystem\n" |
---|
212 | " : ../src/$(SOURCES).cpp\n" |
---|
213 | " : # build requirements\n" |
---|
214 | " [ common-names ] # magic for install and auto-link features\n" |
---|
215 | " <define>BOOST_FILESYSTEM_DYN_LINK=1 # tell source we're building dll's\n" |
---|
216 | " <runtime-link>dynamic # build only for dynamic runtimes\n" |
---|
217 | " <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT)\n" |
---|
218 | " <no-warn>exception.cpp <no-warn>operations_posix_windows.cpp\n" |
---|
219 | " : debug release # build variants\n" |
---|
220 | " ;"; |
---|
221 | |
---|
222 | const std::string output = |
---|
223 | "lib boost_filesystem\n" |
---|
224 | " : ../src/$(SOURCES).cpp\n" |
---|
225 | " : \n" |
---|
226 | " [ common-names ] \n" |
---|
227 | " <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT)\n" |
---|
228 | " <no-warn>exception.cpp <no-warn>operations_posix_windows.cpp\n" |
---|
229 | " : debug release \n" |
---|
230 | " ;\n" |
---|
231 | "\n" |
---|
232 | "dll boost_filesystem\n" |
---|
233 | " : ../src/$(SOURCES).cpp\n" |
---|
234 | " : \n" |
---|
235 | " [ common-names ] \n" |
---|
236 | " <define>BOOST_FILESYSTEM_DYN_LINK=1 \n" |
---|
237 | " <runtime-link>dynamic \n" |
---|
238 | " <include>$(BOOST_ROOT) <sysinclude>$(BOOST_ROOT)\n" |
---|
239 | " <no-warn>exception.cpp <no-warn>operations_posix_windows.cpp\n" |
---|
240 | " : debug release \n" |
---|
241 | " ;"; |
---|
242 | |
---|
243 | BOOST_CHECK( |
---|
244 | io::test_input_filter( io::example::shell_comments_stdio_filter(), |
---|
245 | input, output ) |
---|
246 | ); |
---|
247 | |
---|
248 | BOOST_CHECK( |
---|
249 | io::test_output_filter( io::example::shell_comments_stdio_filter(), |
---|
250 | input, output ) |
---|
251 | ); |
---|
252 | |
---|
253 | BOOST_CHECK( |
---|
254 | io::test_input_filter( io::example::shell_comments_input_filter(), |
---|
255 | input, output ) |
---|
256 | ); |
---|
257 | |
---|
258 | BOOST_CHECK( |
---|
259 | io::test_output_filter( io::example::shell_comments_output_filter(), |
---|
260 | input, output ) |
---|
261 | ); |
---|
262 | |
---|
263 | BOOST_CHECK( |
---|
264 | io::test_input_filter( io::example::shell_comments_dual_use_filter(), |
---|
265 | input, output ) |
---|
266 | ); |
---|
267 | |
---|
268 | BOOST_CHECK( |
---|
269 | io::test_output_filter( io::example::shell_comments_dual_use_filter(), |
---|
270 | input, output ) |
---|
271 | ); |
---|
272 | |
---|
273 | BOOST_CHECK( |
---|
274 | io::test_input_filter( io::example::shell_comments_multichar_input_filter(), |
---|
275 | input, output ) |
---|
276 | ); |
---|
277 | |
---|
278 | BOOST_CHECK( |
---|
279 | io::test_output_filter( io::example::shell_comments_multichar_output_filter(), |
---|
280 | input, output ) |
---|
281 | ); |
---|
282 | } |
---|
283 | |
---|
284 | //------------------tab_expanding_filter test---------------------------------// |
---|
285 | |
---|
286 | void tab_expanding_filter_test() |
---|
287 | { |
---|
288 | using namespace std; |
---|
289 | |
---|
290 | const std::string input = |
---|
291 | "class tab_expanding_stdio_filter : public stdio_filter {\n" |
---|
292 | "public:\n" |
---|
293 | "\texplicit tab_expanding_stdio_filter(int\ttab_size = 8)\n" |
---|
294 | "\t\t: tab_size_(tab_size), col_no_(0)\n" |
---|
295 | "\t{\n" |
---|
296 | "\t\tassert(tab_size\t> 0);\n" |
---|
297 | "\t}\n" |
---|
298 | "private:\n" |
---|
299 | "\tvoid do_filter()\n" |
---|
300 | "\t{\n" |
---|
301 | "\t\tint\tc;\n" |
---|
302 | "\t\twhile ((c = std::cin.get()) != EOF) {\n" |
---|
303 | "\t\t\tif (c == '\\t') {\n" |
---|
304 | "\t\t\t\tint\tspaces = tab_size_ - (col_no_ %\ttab_size_);\n" |
---|
305 | "\t\t\t\tfor\t(; spaces >\t0; --spaces)\n" |
---|
306 | "\t\t\t\t\tput_char(' ');\n" |
---|
307 | "\t\t\t} else {\n" |
---|
308 | "\t\t\t\tput_char(c);\n" |
---|
309 | "\t\t\t}\n" |
---|
310 | "\t\t}\n" |
---|
311 | "\t}\n" |
---|
312 | "\tvoid do_close()\t{ col_no_ =\t0; }\n" |
---|
313 | "\tvoid put_char(int c)\n" |
---|
314 | "\t{\n" |
---|
315 | "\t\tstd::cout.put(c);\n" |
---|
316 | "\t\tif (c == '\\n') {\n" |
---|
317 | "\t\t\tcol_no_\t= 0;\n" |
---|
318 | "\t\t} else {\n" |
---|
319 | "\t\t\t++col_no_;\n" |
---|
320 | "\t\t}\n" |
---|
321 | "\t}\n" |
---|
322 | "\tint\t tab_size_;\n" |
---|
323 | "\tint\t col_no_;\n" |
---|
324 | "};"; |
---|
325 | |
---|
326 | const std::string output = |
---|
327 | "class tab_expanding_stdio_filter : public stdio_filter {\n" |
---|
328 | "public:\n" |
---|
329 | " explicit tab_expanding_stdio_filter(int tab_size = 8)\n" |
---|
330 | " : tab_size_(tab_size), col_no_(0)\n" |
---|
331 | " {\n" |
---|
332 | " assert(tab_size > 0);\n" |
---|
333 | " }\n" |
---|
334 | "private:\n" |
---|
335 | " void do_filter()\n" |
---|
336 | " {\n" |
---|
337 | " int c;\n" |
---|
338 | " while ((c = std::cin.get()) != EOF) {\n" |
---|
339 | " if (c == '\\t') {\n" |
---|
340 | " int spaces = tab_size_ - (col_no_ % tab_size_);\n" |
---|
341 | " for (; spaces > 0; --spaces)\n" |
---|
342 | " put_char(' ');\n" |
---|
343 | " } else {\n" |
---|
344 | " put_char(c);\n" |
---|
345 | " }\n" |
---|
346 | " }\n" |
---|
347 | " }\n" |
---|
348 | " void do_close() { col_no_ = 0; }\n" |
---|
349 | " void put_char(int c)\n" |
---|
350 | " {\n" |
---|
351 | " std::cout.put(c);\n" |
---|
352 | " if (c == '\\n') {\n" |
---|
353 | " col_no_ = 0;\n" |
---|
354 | " } else {\n" |
---|
355 | " ++col_no_;\n" |
---|
356 | " }\n" |
---|
357 | " }\n" |
---|
358 | " int tab_size_;\n" |
---|
359 | " int col_no_;\n" |
---|
360 | "};"; |
---|
361 | |
---|
362 | BOOST_CHECK( |
---|
363 | io::test_input_filter( io::example::tab_expanding_stdio_filter(4), |
---|
364 | input, output ) |
---|
365 | ); |
---|
366 | |
---|
367 | BOOST_CHECK( |
---|
368 | io::test_output_filter( io::example::tab_expanding_stdio_filter(4), |
---|
369 | input, output ) |
---|
370 | ); |
---|
371 | |
---|
372 | BOOST_CHECK( |
---|
373 | io::test_input_filter( io::example::tab_expanding_input_filter(4), |
---|
374 | input, output ) |
---|
375 | ); |
---|
376 | |
---|
377 | BOOST_CHECK( |
---|
378 | io::test_output_filter( io::example::tab_expanding_output_filter(4), |
---|
379 | input, output ) |
---|
380 | ); |
---|
381 | } |
---|
382 | |
---|
383 | //------------------unix2dos_filter test--------------------------------------// |
---|
384 | |
---|
385 | void unix2dos_filter_test() |
---|
386 | { |
---|
387 | using namespace std; |
---|
388 | |
---|
389 | const std::string input = |
---|
390 | "When I was one-and-twenty\n" |
---|
391 | "I heard a wise man say,\n" |
---|
392 | "'Give crowns and pounds and guineas\n" |
---|
393 | "But not your heart away;\n" |
---|
394 | "\n" |
---|
395 | "Give pearls away and rubies\n" |
---|
396 | "But keep your fancy free.'\n" |
---|
397 | "But I was one-and-twenty,\n" |
---|
398 | "No use to talk to me.\n" |
---|
399 | "\n" |
---|
400 | "When I was one-and-twenty\n" |
---|
401 | "I heard him say again,\n" |
---|
402 | "'The heart out of the bosom\n" |
---|
403 | "Was never given in vain;\n" |
---|
404 | "'Tis paid with sighs a plenty\n" |
---|
405 | "And sold for endless rue.'\n" |
---|
406 | "And I am two-and-twenty,\n" |
---|
407 | "And oh, 'tis true, 'tis true."; |
---|
408 | |
---|
409 | const std::string output = |
---|
410 | "When I was one-and-twenty\r\n" |
---|
411 | "I heard a wise man say,\r\n" |
---|
412 | "'Give crowns and pounds and guineas\r\n" |
---|
413 | "But not your heart away;\r\n" |
---|
414 | "\r\n" |
---|
415 | "Give pearls away and rubies\r\n" |
---|
416 | "But keep your fancy free.'\r\n" |
---|
417 | "But I was one-and-twenty,\r\n" |
---|
418 | "No use to talk to me.\r\n" |
---|
419 | "\r\n" |
---|
420 | "When I was one-and-twenty\r\n" |
---|
421 | "I heard him say again,\r\n" |
---|
422 | "'The heart out of the bosom\r\n" |
---|
423 | "Was never given in vain;\r\n" |
---|
424 | "'Tis paid with sighs a plenty\r\n" |
---|
425 | "And sold for endless rue.'\r\n" |
---|
426 | "And I am two-and-twenty,\r\n" |
---|
427 | "And oh, 'tis true, 'tis true."; |
---|
428 | |
---|
429 | BOOST_CHECK( |
---|
430 | io::test_input_filter( io::example::unix2dos_stdio_filter(), |
---|
431 | input, output ) |
---|
432 | ); |
---|
433 | |
---|
434 | BOOST_CHECK( |
---|
435 | io::test_output_filter( io::example::unix2dos_stdio_filter(), |
---|
436 | input, output ) |
---|
437 | ); |
---|
438 | |
---|
439 | BOOST_CHECK( |
---|
440 | io::test_input_filter( io::example::unix2dos_input_filter(), |
---|
441 | input, output ) |
---|
442 | ); |
---|
443 | |
---|
444 | BOOST_CHECK( |
---|
445 | io::test_output_filter( io::example::unix2dos_output_filter(), |
---|
446 | input, output ) |
---|
447 | ); |
---|
448 | } |
---|
449 | |
---|
450 | test_suite* init_unit_test_suite(int, char* []) |
---|
451 | { |
---|
452 | test_suite* test = BOOST_TEST_SUITE("example test"); |
---|
453 | test->add(BOOST_TEST_CASE(&container_device_test)); |
---|
454 | test->add(BOOST_TEST_CASE(&dictionary_filter_test)); |
---|
455 | test->add(BOOST_TEST_CASE(&tab_expanding_filter_test)); |
---|
456 | test->add(BOOST_TEST_CASE(&line_wrapping_filter_test)); |
---|
457 | test->add(BOOST_TEST_CASE(&shell_comments_filter_test)); |
---|
458 | test->add(BOOST_TEST_CASE(&unix2dos_filter_test)); |
---|
459 | return test; |
---|
460 | } |
---|