1 /*
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 * Verifies that the close() member functions of filters and devices
8 * are called with the correct arguments in the correct order when
9 * they are combined using combine().
10 *
11 * File: libs/iostreams/test/combine_test.cpp
12 * Date: Sun Jan 06 01:37:37 MST 2008
13 * Copyright: 2007-2008 CodeRage, LLC
14 * Author: Jonathan Turkanis
15 * Contact: turkanis at coderage dot com
16 */
17
18 #include <boost/iostreams/chain.hpp>
19 #include <boost/iostreams/combine.hpp>
20 #include <boost/test/test_tools.hpp>
21 #include <boost/test/unit_test.hpp>
22 #include "detail/closable.hpp"
23 #include "detail/operation_sequence.hpp"
24
25 using namespace boost::iostreams;
26 using namespace boost::iostreams::test;
27 using boost::unit_test::test_suite;
28 namespace io = boost::iostreams;
29
combine_test()30 void combine_test()
31 {
32 // Combine a source and a sink
33 {
34 operation_sequence seq;
35 chain<bidirectional> ch;
36 ch.push(
37 io::combine(
38 closable_device<input>(seq.new_operation(1)),
39 closable_device<output>(seq.new_operation(2))
40 )
41 );
42 BOOST_CHECK_NO_THROW(ch.reset());
43 BOOST_CHECK_OPERATION_SEQUENCE(seq);
44 }
45
46 // Combine two bidirectional devices
47 {
48 operation_sequence seq;
49 chain<bidirectional> ch;
50 ch.push(
51 io::combine(
52 closable_device<bidirectional>(
53 seq.new_operation(1),
54 seq.new_operation(2)
55 ),
56 closable_device<bidirectional>(
57 seq.new_operation(3),
58 seq.new_operation(4)
59 )
60 )
61 );
62 BOOST_CHECK_NO_THROW(ch.reset());
63 BOOST_CHECK_OPERATION_SEQUENCE(seq);
64 }
65
66 // Combine two seekable devices
67 {
68 operation_sequence seq;
69 chain<bidirectional> ch;
70 ch.push(
71 io::combine(
72 closable_device<seekable>(seq.new_operation(1)),
73 closable_device<seekable>(seq.new_operation(2))
74 )
75 );
76 BOOST_CHECK_NO_THROW(ch.reset());
77 BOOST_CHECK_OPERATION_SEQUENCE(seq);
78 }
79
80 // Combine an input filter and an output filter
81 {
82 operation_sequence seq;
83 chain<bidirectional> ch;
84 ch.push(
85 io::combine(
86 closable_filter<input>(seq.new_operation(2)),
87 closable_filter<output>(seq.new_operation(3))
88 )
89 );
90 ch.push(
91 closable_device<bidirectional>(
92 seq.new_operation(1),
93 seq.new_operation(4)
94 )
95 );
96 BOOST_CHECK_NO_THROW(ch.reset());
97 BOOST_CHECK_OPERATION_SEQUENCE(seq);
98 }
99
100 // Combine two bidirectional filters
101 {
102 operation_sequence seq;
103 chain<bidirectional> ch;
104 ch.push(
105 io::combine(
106 closable_filter<bidirectional>(
107 seq.new_operation(2),
108 seq.new_operation(3)
109 ),
110 closable_filter<bidirectional>(
111 seq.new_operation(4),
112 seq.new_operation(5)
113 )
114 )
115 );
116 ch.push(
117 closable_device<bidirectional>(
118 seq.new_operation(1),
119 seq.new_operation(6)
120 )
121 );
122 BOOST_CHECK_NO_THROW(ch.reset());
123 BOOST_CHECK_OPERATION_SEQUENCE(seq);
124 }
125
126 // Combine two seekable filters
127 {
128 operation_sequence seq;
129 chain<bidirectional> ch;
130 ch.push(
131 io::combine(
132 closable_filter<seekable>(seq.new_operation(2)),
133 closable_filter<seekable>(seq.new_operation(3))
134 )
135 );
136 ch.push(
137 closable_device<bidirectional>(
138 seq.new_operation(1),
139 seq.new_operation(4)
140 )
141 );
142 BOOST_CHECK_NO_THROW(ch.reset());
143 BOOST_CHECK_OPERATION_SEQUENCE(seq);
144 }
145
146 // Combine a dual-use filter and an input filter
147 {
148 operation_sequence seq;
149 chain<bidirectional> ch;
150 operation dummy;
151 ch.push(
152 io::combine(
153 closable_filter<input>(seq.new_operation(2)),
154 closable_filter<dual_use>(
155 dummy,
156 seq.new_operation(3)
157 )
158 )
159 );
160 ch.push(
161 closable_device<bidirectional>(
162 seq.new_operation(1),
163 seq.new_operation(4)
164 )
165 );
166 BOOST_CHECK_NO_THROW(ch.reset());
167 BOOST_CHECK_OPERATION_SEQUENCE(seq);
168 }
169
170 // Combine a dual-use filter and an output filter
171 {
172 operation_sequence seq;
173 chain<bidirectional> ch;
174 operation dummy;
175 ch.push(
176 io::combine(
177 closable_filter<dual_use>(
178 seq.new_operation(2),
179 dummy
180 ),
181 closable_filter<output>(seq.new_operation(3))
182 )
183 );
184 ch.push(
185 closable_device<bidirectional>(
186 seq.new_operation(1),
187 seq.new_operation(4)
188 )
189 );
190 BOOST_CHECK_NO_THROW(ch.reset());
191 BOOST_CHECK_OPERATION_SEQUENCE(seq);
192 }
193
194 // Combine two dual-use filters
195 {
196 operation_sequence seq;
197 chain<bidirectional> ch;
198 operation dummy;
199 ch.push(
200 io::combine(
201 closable_filter<dual_use>(
202 seq.new_operation(2),
203 dummy
204 ),
205 closable_filter<dual_use>(
206 dummy,
207 seq.new_operation(3)
208 )
209 )
210 );
211 ch.push(
212 closable_device<bidirectional>(
213 seq.new_operation(1),
214 seq.new_operation(4)
215 )
216 );
217 BOOST_CHECK_NO_THROW(ch.reset());
218 BOOST_CHECK_OPERATION_SEQUENCE(seq);
219 }
220 }
221
init_unit_test_suite(int,char * [])222 test_suite* init_unit_test_suite(int, char* [])
223 {
224 test_suite* test = BOOST_TEST_SUITE("combine test");
225 test->add(BOOST_TEST_CASE(&combine_test));
226 return test;
227 }
228