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