@@ -182,32 +182,40 @@ impl Transaction {
182182}
183183
184184/// Mock IO implementation
185- pub type Mock = Generic < Transaction > ;
185+ pub type Mock = Generic < Transaction , Vec < u8 > > ;
186186
187187impl ErrorType for Mock {
188188 type Error = ErrorKind ;
189189}
190190
191191impl Write for Mock {
192192 fn write ( & mut self , buffer : & [ u8 ] ) -> Result < usize , Self :: Error > {
193- let w = self . next ( ) . expect ( "no expectation for io::write call" ) ;
194- assert_eq ! ( w. expected_mode, Mode :: Write , "io::write unexpected mode" ) ;
193+ let transaction = self . next ( ) . expect ( "no expectation for io::write call" ) ;
195194 assert_eq ! (
196- & w. expected_data, & buffer,
195+ transaction. expected_mode,
196+ Mode :: Write ,
197+ "io::write unexpected mode"
198+ ) ;
199+ assert_eq ! (
200+ & transaction. expected_data, & buffer,
197201 "io::write data does not match expectation"
198202 ) ;
199203
200- match w . expected_err {
204+ match transaction . expected_err {
201205 Some ( err) => Err ( err) ,
202206 None => Ok ( buffer. len ( ) ) ,
203207 }
204208 }
205209
206210 fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
207- let w = self . next ( ) . expect ( "no expectation for io::flush call" ) ;
208- assert_eq ! ( w. expected_mode, Mode :: Flush , "io::flush unexpected mode" ) ;
211+ let transaction = self . next ( ) . expect ( "no expectation for io::flush call" ) ;
212+ assert_eq ! (
213+ transaction. expected_mode,
214+ Mode :: Flush ,
215+ "io::flush unexpected mode"
216+ ) ;
209217
210- match w . expected_err {
218+ match transaction . expected_err {
211219 Some ( err) => Err ( err) ,
212220 None => Ok ( ( ) ) ,
213221 }
@@ -216,91 +224,116 @@ impl Write for Mock {
216224
217225impl Read for Mock {
218226 fn read ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , Self :: Error > {
219- let w = self . next ( ) . expect ( "no expectation for io::read call" ) ;
220- assert_eq ! ( w. expected_mode, Mode :: Read , "io::read unexpected mode" ) ;
221- buffer. copy_from_slice ( & w. response ) ;
227+ let transaction = self . next ( ) . expect ( "no expectation for io::read call" ) ;
228+ assert_eq ! (
229+ transaction. expected_mode,
230+ Mode :: Read ,
231+ "io::read unexpected mode"
232+ ) ;
222233
223- match w. expected_err {
234+ if transaction. response . len ( ) > buffer. len ( ) {
235+ panic ! ( "response longer than read buffer for io::read" ) ;
236+ }
237+
238+ let len = std:: cmp:: min ( buffer. len ( ) , transaction. response . len ( ) ) ;
239+ buffer[ ..len] . copy_from_slice ( & transaction. response [ ..len] ) ;
240+
241+ match transaction. expected_err {
224242 Some ( err) => Err ( err) ,
225- None => Ok ( buffer . len ( ) ) ,
243+ None => Ok ( len) ,
226244 }
227245 }
228246}
229247
230248impl Seek for Mock {
231249 fn seek ( & mut self , pos : SeekFrom ) -> Result < u64 , Self :: Error > {
232- let w = self . next ( ) . expect ( "no expectation for io::seek call" ) ;
250+ let transaction = self . next ( ) . expect ( "no expectation for io::seek call" ) ;
233251
234- if let Mode :: Seek ( expected_pos) = w . expected_mode {
252+ if let Mode :: Seek ( expected_pos) = transaction . expected_mode {
235253 assert_eq ! ( expected_pos, pos, "io::seek unexpected mode" ) ;
236254
237- let ret_offset: u64 = u64:: from_be_bytes ( w . response . try_into ( ) . unwrap ( ) ) ;
238- match w . expected_err {
255+ let ret_offset: u64 = u64:: from_be_bytes ( transaction . response . try_into ( ) . unwrap ( ) ) ;
256+ match transaction . expected_err {
239257 Some ( err) => Err ( err) ,
240258 None => Ok ( ret_offset) ,
241259 }
242260 } else {
243- panic ! ( "unexpected seek mode" ) ;
261+ panic ! (
262+ "expected seek transaction, but instead encountered {:?}. io::seek unexpected mode" ,
263+ transaction. expected_mode
264+ ) ;
244265 }
245266 }
246267}
247268
248269impl WriteReady for Mock {
249270 fn write_ready ( & mut self ) -> Result < bool , Self :: Error > {
250- let w = self
271+ let transaction = self
251272 . next ( )
252273 . expect ( "no expectation for io::write_ready call" ) ;
253274
254- match w. expected_mode {
255- Mode :: WriteReady ( ready) if w. expected_err . is_none ( ) => Ok ( ready) ,
256- Mode :: WriteReady ( _) if w. expected_err . is_some ( ) => Err ( w. expected_err . unwrap ( ) ) ,
257- _ => panic ! ( "unexpected write_ready mode" ) ,
275+ match transaction. expected_mode {
276+ Mode :: WriteReady ( ready) if transaction. expected_err . is_none ( ) => Ok ( ready) ,
277+ Mode :: WriteReady ( _) if transaction. expected_err . is_some ( ) => {
278+ Err ( transaction. expected_err . unwrap ( ) )
279+ }
280+ _ => panic ! (
281+ "expected write_ready transaction, but instead encountered {:?}. io::write_ready unexpected mode" ,
282+ transaction. expected_mode
283+ ) ,
258284 }
259285 }
260286}
261287
262288impl ReadReady for Mock {
263289 fn read_ready ( & mut self ) -> Result < bool , Self :: Error > {
264- let w = self . next ( ) . expect ( "no expectation for io::read_ready call" ) ;
290+ let transaction = self . next ( ) . expect ( "no expectation for io::read_ready call" ) ;
265291
266- match w. expected_mode {
267- Mode :: ReadReady ( ready) if w. expected_err . is_none ( ) => Ok ( ready) ,
268- Mode :: ReadReady ( _) if w. expected_err . is_some ( ) => Err ( w. expected_err . unwrap ( ) ) ,
269- _ => panic ! ( "unexpected read_ready mode" ) ,
292+ match transaction. expected_mode {
293+ Mode :: ReadReady ( ready) if transaction. expected_err . is_none ( ) => Ok ( ready) ,
294+ Mode :: ReadReady ( _) if transaction. expected_err . is_some ( ) => {
295+ Err ( transaction. expected_err . unwrap ( ) )
296+ }
297+ _ => panic ! (
298+ "expected read_ready transaction, but instead encountered {:?}. io::read_ready unexpected mode" ,
299+ transaction. expected_mode
300+ )
270301 }
271302 }
272303}
273304
274305impl BufRead for Mock {
275306 fn fill_buf ( & mut self ) -> Result < & [ u8 ] , Self :: Error > {
276- let w = self . next ( ) . expect ( "no expectation for io::fill_buf call" ) ;
307+ let transaction = self . next ( ) . expect ( "no expectation for io::fill_buf call" ) ;
277308 assert_eq ! (
278- w . expected_mode,
309+ transaction . expected_mode,
279310 Mode :: FillBuff ,
280311 "io::fill_buf unexpected mode"
281312 ) ;
282313
283- let response_vec = w. response ;
314+ let response_vec = transaction. response ;
315+ self . set_mock_data ( Some ( response_vec) ) ;
284316
285- match w . expected_err {
317+ match transaction . expected_err {
286318 Some ( err) => Err ( err) ,
287-
288- // SAFETY : This is a memory leak. This is done on purpose to allow for a return
289- // of a slice (pointer) to the internal buffer, which doesn't exist in mock implementation.
290- // This way, after each call, response is going to be put on the heap and ref is going to be returned, without freeing this memory.
291- // For mocking purposes this should be an acceptable solution.
292- None => Ok ( Box :: leak ( response_vec. into_boxed_slice ( ) ) ) ,
319+ None => Ok ( self . mock_data ( ) . as_ref ( ) . unwrap ( ) ) ,
293320 }
294321 }
295322
296323 fn consume ( & mut self , amt : usize ) {
297- let w = self . next ( ) . expect ( "no expectation for io::consume call" ) ;
324+ let transaction = self . next ( ) . expect ( "no expectation for io::consume call" ) ;
298325
299- match w . expected_mode {
300- Mode :: Consume ( expected_amt) if w . expected_err . is_none ( ) => {
326+ match transaction . expected_mode {
327+ Mode :: Consume ( expected_amt) if transaction . expected_err . is_none ( ) => {
301328 assert_eq ! ( expected_amt, amt, "io::consume unexpected amount" ) ;
302329 }
303- _ => panic ! ( "unexpected consume mode" ) ,
330+ Mode :: Consume ( _) if transaction. expected_err . is_some ( ) => {
331+ panic ! ( "io::consume can't expect an error. io::consume unexpected error" ) ;
332+ }
333+ _ => panic ! (
334+ "expected consume transaction, but instead encountered {:?}. io::consume unexpected mode" ,
335+ transaction. expected_mode
336+ )
304337 }
305338 }
306339}
@@ -401,6 +434,19 @@ mod test {
401434 io. done ( ) ;
402435 }
403436
437+ #[ test]
438+ fn test_io_mock_read_buffer_to_long ( ) {
439+ let mut io = Mock :: new ( & [ Transaction :: read ( vec ! [ 10 ] ) ] ) ;
440+
441+ let mut buffer = [ 0 ; 3 ] ;
442+ let ret = io. read ( & mut buffer) . unwrap ( ) ;
443+
444+ assert_eq ! ( buffer, [ 10 , 0 , 0 ] ) ;
445+ assert_eq ! ( ret, 1 ) ;
446+
447+ io. done ( ) ;
448+ }
449+
404450 #[ tokio:: test]
405451 #[ cfg( feature = "embedded-hal-async" ) ]
406452 async fn test_async_io_mock_read ( ) {
@@ -466,12 +512,17 @@ mod test {
466512
467513 #[ test]
468514 fn test_io_mock_fill_buf ( ) {
469- let mut io = Mock :: new ( & [ Transaction :: fill_buf ( vec ! [ 10 ] ) ] ) ;
515+ let mut io = Mock :: new ( & [
516+ Transaction :: fill_buf ( vec ! [ 10 ] ) ,
517+ Transaction :: fill_buf ( vec ! [ 10 , 20 , 30 ] ) ,
518+ ] ) ;
470519
471520 let ret = io. fill_buf ( ) . unwrap ( ) ;
472-
473521 assert_eq ! ( ret, & [ 10 ] ) ;
474522
523+ let ret = io. fill_buf ( ) . unwrap ( ) ;
524+ assert_eq ! ( ret, & [ 10 , 20 , 30 ] ) ;
525+
475526 io. done ( ) ;
476527 }
477528
@@ -548,6 +599,20 @@ mod test {
548599 io. done ( ) ;
549600 }
550601
602+ #[ test]
603+ #[ should_panic( expected = "response longer than read buffer for io::read" ) ]
604+ fn test_io_mock_read_buffer_to_short ( ) {
605+ let mut io = Mock :: new ( & [ Transaction :: read ( vec ! [ 10 , 20 , 30 ] ) ] ) ;
606+
607+ let mut buffer = [ 0 ; 1 ] ;
608+ let ret = io. read ( & mut buffer) . unwrap ( ) ;
609+
610+ assert_eq ! ( buffer, [ 10 ] ) ;
611+ assert_eq ! ( ret, 1 ) ;
612+
613+ io. done ( ) ;
614+ }
615+
551616 #[ test]
552617 #[ should_panic( expected = "io::seek unexpected mode" ) ]
553618 fn test_io_mock_seek_err ( ) {
0 commit comments