1 use futures::executor::block_on;
2 use futures::future::{Future, FutureExt};
3 use futures::io::{AsyncBufReadExt, Cursor};
4 use futures::stream::{self, StreamExt, TryStreamExt};
5 use futures::task::Poll;
6 use futures::AsyncRead;
7 use futures_test::io::AsyncReadTestExt;
8 use futures_test::task::noop_context;
9
run<F: Future + Unpin>(mut f: F) -> F::Output10 fn run<F: Future + Unpin>(mut f: F) -> F::Output {
11 let mut cx = noop_context();
12 loop {
13 if let Poll::Ready(x) = f.poll_unpin(&mut cx) {
14 return x;
15 }
16 }
17 }
18
19 struct IOErrorRead(bool);
20
21 impl AsyncRead for IOErrorRead {
poll_read( mut self: std::pin::Pin<&mut Self>, _cx: &mut std::task::Context<'_>, b: &mut [u8], ) -> Poll<std::io::Result<usize>>22 fn poll_read(
23 mut self: std::pin::Pin<&mut Self>,
24 _cx: &mut std::task::Context<'_>,
25 b: &mut [u8],
26 ) -> Poll<std::io::Result<usize>> {
27 if self.0 {
28 Poll::Ready(Err(std::io::ErrorKind::InvalidInput.into()))
29 } else {
30 self.0 = true;
31 b[..16].fill(b'x');
32 Ok(16).into()
33 }
34 }
35 }
36
37 #[test]
read_line()38 fn read_line() {
39 let mut buf = Cursor::new(b"12");
40 let mut v = String::new();
41 assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 2);
42 assert_eq!(v, "12");
43
44 let mut buf = Cursor::new(b"12\n\n");
45 let mut v = String::new();
46 assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 3);
47 assert_eq!(v, "12\n");
48 v.clear();
49 assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 1);
50 assert_eq!(v, "\n");
51 v.clear();
52 assert_eq!(block_on(buf.read_line(&mut v)).unwrap(), 0);
53 assert_eq!(v, "");
54 }
55
56 #[test]
read_line_drop()57 fn read_line_drop() {
58 // string contents should be preserved if the future is dropped
59 let mut buf = Cursor::new(b"12\n\n");
60 let mut v = String::from("abc");
61 drop(buf.read_line(&mut v));
62 assert_eq!(v, "abc");
63 }
64
65 #[test]
read_line_io_error()66 fn read_line_io_error() {
67 let mut r = futures::io::BufReader::new(IOErrorRead(false));
68 let _ = block_on(r.read_line(&mut String::new()));
69 }
70
71 #[test]
read_line_utf8_error()72 fn read_line_utf8_error() {
73 let mut buf = Cursor::new(b"12\xFF\n\n");
74 let mut v = String::from("abc");
75 let res = block_on(buf.read_line(&mut v));
76 assert_eq!(res.unwrap_err().kind(), std::io::ErrorKind::InvalidData);
77 assert_eq!(v, "abc");
78 }
79
80 #[test]
maybe_pending()81 fn maybe_pending() {
82 let mut buf = b"12".interleave_pending();
83 let mut v = String::new();
84 assert_eq!(run(buf.read_line(&mut v)).unwrap(), 2);
85 assert_eq!(v, "12");
86
87 let mut buf =
88 stream::iter(vec![&b"12"[..], &b"\n\n"[..]]).map(Ok).into_async_read().interleave_pending();
89 let mut v = String::new();
90 assert_eq!(run(buf.read_line(&mut v)).unwrap(), 3);
91 assert_eq!(v, "12\n");
92 v.clear();
93 assert_eq!(run(buf.read_line(&mut v)).unwrap(), 1);
94 assert_eq!(v, "\n");
95 v.clear();
96 assert_eq!(run(buf.read_line(&mut v)).unwrap(), 0);
97 assert_eq!(v, "");
98 v.clear();
99 assert_eq!(run(buf.read_line(&mut v)).unwrap(), 0);
100 assert_eq!(v, "");
101 }
102