diff options
Diffstat (limited to 'library/std/src/io/mod.rs')
| -rw-r--r-- | library/std/src/io/mod.rs | 501 |
1 files changed, 3 insertions, 498 deletions
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 462b696db40..adea8a804e3 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -249,6 +249,9 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[cfg(test)] +mod tests; + use crate::cmp; use crate::fmt; use crate::memchr; @@ -2481,501 +2484,3 @@ impl<B: BufRead> Iterator for Lines<B> { } } } - -#[cfg(test)] -mod tests { - use super::{repeat, Cursor, SeekFrom}; - use crate::cmp::{self, min}; - use crate::io::prelude::*; - use crate::io::{self, IoSlice, IoSliceMut}; - use crate::ops::Deref; - - #[test] - #[cfg_attr(target_os = "emscripten", ignore)] - fn read_until() { - let mut buf = Cursor::new(&b"12"[..]); - let mut v = Vec::new(); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2); - assert_eq!(v, b"12"); - - let mut buf = Cursor::new(&b"1233"[..]); - let mut v = Vec::new(); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3); - assert_eq!(v, b"123"); - v.truncate(0); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1); - assert_eq!(v, b"3"); - v.truncate(0); - assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0); - assert_eq!(v, []); - } - - #[test] - fn split() { - let buf = Cursor::new(&b"12"[..]); - let mut s = buf.split(b'3'); - assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); - assert!(s.next().is_none()); - - let buf = Cursor::new(&b"1233"[..]); - let mut s = buf.split(b'3'); - assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']); - assert_eq!(s.next().unwrap().unwrap(), vec![]); - assert!(s.next().is_none()); - } - - #[test] - fn read_line() { - let mut buf = Cursor::new(&b"12"[..]); - let mut v = String::new(); - assert_eq!(buf.read_line(&mut v).unwrap(), 2); - assert_eq!(v, "12"); - - let mut buf = Cursor::new(&b"12\n\n"[..]); - let mut v = String::new(); - assert_eq!(buf.read_line(&mut v).unwrap(), 3); - assert_eq!(v, "12\n"); - v.truncate(0); - assert_eq!(buf.read_line(&mut v).unwrap(), 1); - assert_eq!(v, "\n"); - v.truncate(0); - assert_eq!(buf.read_line(&mut v).unwrap(), 0); - assert_eq!(v, ""); - } - - #[test] - fn lines() { - let buf = Cursor::new(&b"12\r"[..]); - let mut s = buf.lines(); - assert_eq!(s.next().unwrap().unwrap(), "12\r".to_string()); - assert!(s.next().is_none()); - - let buf = Cursor::new(&b"12\r\n\n"[..]); - let mut s = buf.lines(); - assert_eq!(s.next().unwrap().unwrap(), "12".to_string()); - assert_eq!(s.next().unwrap().unwrap(), "".to_string()); - assert!(s.next().is_none()); - } - - #[test] - fn read_to_end() { - let mut c = Cursor::new(&b""[..]); - let mut v = Vec::new(); - assert_eq!(c.read_to_end(&mut v).unwrap(), 0); - assert_eq!(v, []); - - let mut c = Cursor::new(&b"1"[..]); - let mut v = Vec::new(); - assert_eq!(c.read_to_end(&mut v).unwrap(), 1); - assert_eq!(v, b"1"); - - let cap = 1024 * 1024; - let data = (0..cap).map(|i| (i / 3) as u8).collect::<Vec<_>>(); - let mut v = Vec::new(); - let (a, b) = data.split_at(data.len() / 2); - assert_eq!(Cursor::new(a).read_to_end(&mut v).unwrap(), a.len()); - assert_eq!(Cursor::new(b).read_to_end(&mut v).unwrap(), b.len()); - assert_eq!(v, data); - } - - #[test] - fn read_to_string() { - let mut c = Cursor::new(&b""[..]); - let mut v = String::new(); - assert_eq!(c.read_to_string(&mut v).unwrap(), 0); - assert_eq!(v, ""); - - let mut c = Cursor::new(&b"1"[..]); - let mut v = String::new(); - assert_eq!(c.read_to_string(&mut v).unwrap(), 1); - assert_eq!(v, "1"); - - let mut c = Cursor::new(&b"\xff"[..]); - let mut v = String::new(); - assert!(c.read_to_string(&mut v).is_err()); - } - - #[test] - fn read_exact() { - let mut buf = [0; 4]; - - let mut c = Cursor::new(&b""[..]); - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - - let mut c = Cursor::new(&b"123"[..]).chain(Cursor::new(&b"456789"[..])); - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"1234"); - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"5678"); - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - } - - #[test] - fn read_exact_slice() { - let mut buf = [0; 4]; - - let mut c = &b""[..]; - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - - let mut c = &b"123"[..]; - assert_eq!(c.read_exact(&mut buf).unwrap_err().kind(), io::ErrorKind::UnexpectedEof); - // make sure the optimized (early returning) method is being used - assert_eq!(&buf, &[0; 4]); - - let mut c = &b"1234"[..]; - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"1234"); - - let mut c = &b"56789"[..]; - c.read_exact(&mut buf).unwrap(); - assert_eq!(&buf, b"5678"); - assert_eq!(c, b"9"); - } - - #[test] - fn take_eof() { - struct R; - - impl Read for R { - fn read(&mut self, _: &mut [u8]) -> io::Result<usize> { - Err(io::Error::new(io::ErrorKind::Other, "")) - } - } - impl BufRead for R { - fn fill_buf(&mut self) -> io::Result<&[u8]> { - Err(io::Error::new(io::ErrorKind::Other, "")) - } - fn consume(&mut self, _amt: usize) {} - } - - let mut buf = [0; 1]; - assert_eq!(0, R.take(0).read(&mut buf).unwrap()); - assert_eq!(b"", R.take(0).fill_buf().unwrap()); - } - - fn cmp_bufread<Br1: BufRead, Br2: BufRead>(mut br1: Br1, mut br2: Br2, exp: &[u8]) { - let mut cat = Vec::new(); - loop { - let consume = { - let buf1 = br1.fill_buf().unwrap(); - let buf2 = br2.fill_buf().unwrap(); - let minlen = if buf1.len() < buf2.len() { buf1.len() } else { buf2.len() }; - assert_eq!(buf1[..minlen], buf2[..minlen]); - cat.extend_from_slice(&buf1[..minlen]); - minlen - }; - if consume == 0 { - break; - } - br1.consume(consume); - br2.consume(consume); - } - assert_eq!(br1.fill_buf().unwrap().len(), 0); - assert_eq!(br2.fill_buf().unwrap().len(), 0); - assert_eq!(&cat[..], &exp[..]) - } - - #[test] - fn chain_bufread() { - let testdata = b"ABCDEFGHIJKL"; - let chain1 = - (&testdata[..3]).chain(&testdata[3..6]).chain(&testdata[6..9]).chain(&testdata[9..]); - let chain2 = (&testdata[..4]).chain(&testdata[4..8]).chain(&testdata[8..]); - cmp_bufread(chain1, chain2, &testdata[..]); - } - - #[test] - fn chain_zero_length_read_is_not_eof() { - let a = b"A"; - let b = b"B"; - let mut s = String::new(); - let mut chain = (&a[..]).chain(&b[..]); - chain.read(&mut []).unwrap(); - chain.read_to_string(&mut s).unwrap(); - assert_eq!("AB", s); - } - - #[bench] - #[cfg_attr(target_os = "emscripten", ignore)] - fn bench_read_to_end(b: &mut test::Bencher) { - b.iter(|| { - let mut lr = repeat(1).take(10000000); - let mut vec = Vec::with_capacity(1024); - super::read_to_end(&mut lr, &mut vec) - }); - } - - #[test] - fn seek_len() -> io::Result<()> { - let mut c = Cursor::new(vec![0; 15]); - assert_eq!(c.stream_len()?, 15); - - c.seek(SeekFrom::End(0))?; - let old_pos = c.stream_position()?; - assert_eq!(c.stream_len()?, 15); - assert_eq!(c.stream_position()?, old_pos); - - c.seek(SeekFrom::Start(7))?; - c.seek(SeekFrom::Current(2))?; - let old_pos = c.stream_position()?; - assert_eq!(c.stream_len()?, 15); - assert_eq!(c.stream_position()?, old_pos); - - Ok(()) - } - - #[test] - fn seek_position() -> io::Result<()> { - // All `asserts` are duplicated here to make sure the method does not - // change anything about the seek state. - let mut c = Cursor::new(vec![0; 15]); - assert_eq!(c.stream_position()?, 0); - assert_eq!(c.stream_position()?, 0); - - c.seek(SeekFrom::End(0))?; - assert_eq!(c.stream_position()?, 15); - assert_eq!(c.stream_position()?, 15); - - c.seek(SeekFrom::Start(7))?; - c.seek(SeekFrom::Current(2))?; - assert_eq!(c.stream_position()?, 9); - assert_eq!(c.stream_position()?, 9); - - c.seek(SeekFrom::End(-3))?; - c.seek(SeekFrom::Current(1))?; - c.seek(SeekFrom::Current(-5))?; - assert_eq!(c.stream_position()?, 8); - assert_eq!(c.stream_position()?, 8); - - Ok(()) - } - - // A simple example reader which uses the default implementation of - // read_to_end. - struct ExampleSliceReader<'a> { - slice: &'a [u8], - } - - impl<'a> Read for ExampleSliceReader<'a> { - fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - let len = cmp::min(self.slice.len(), buf.len()); - buf[..len].copy_from_slice(&self.slice[..len]); - self.slice = &self.slice[len..]; - Ok(len) - } - } - - #[test] - fn test_read_to_end_capacity() -> io::Result<()> { - let input = &b"foo"[..]; - - // read_to_end() generally needs to over-allocate, both for efficiency - // and so that it can distinguish EOF. Assert that this is the case - // with this simple ExampleSliceReader struct, which uses the default - // implementation of read_to_end. Even though vec1 is allocated with - // exactly enough capacity for the read, read_to_end will allocate more - // space here. - let mut vec1 = Vec::with_capacity(input.len()); - ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; - assert_eq!(vec1.len(), input.len()); - assert!(vec1.capacity() > input.len(), "allocated more"); - - // However, std::io::Take includes an implementation of read_to_end - // that will not allocate when the limit has already been reached. In - // this case, vec2 never grows. - let mut vec2 = Vec::with_capacity(input.len()); - ExampleSliceReader { slice: input }.take(input.len() as u64).read_to_end(&mut vec2)?; - assert_eq!(vec2.len(), input.len()); - assert_eq!(vec2.capacity(), input.len(), "did not allocate more"); - - Ok(()) - } - - #[test] - fn io_slice_mut_advance() { - let mut buf1 = [1; 8]; - let mut buf2 = [2; 16]; - let mut buf3 = [3; 8]; - let mut bufs = &mut [ - IoSliceMut::new(&mut buf1), - IoSliceMut::new(&mut buf2), - IoSliceMut::new(&mut buf3), - ][..]; - - // Only in a single buffer.. - bufs = IoSliceMut::advance(bufs, 1); - assert_eq!(bufs[0].deref(), [1; 7].as_ref()); - assert_eq!(bufs[1].deref(), [2; 16].as_ref()); - assert_eq!(bufs[2].deref(), [3; 8].as_ref()); - - // Removing a buffer, leaving others as is. - bufs = IoSliceMut::advance(bufs, 7); - assert_eq!(bufs[0].deref(), [2; 16].as_ref()); - assert_eq!(bufs[1].deref(), [3; 8].as_ref()); - - // Removing a buffer and removing from the next buffer. - bufs = IoSliceMut::advance(bufs, 18); - assert_eq!(bufs[0].deref(), [3; 6].as_ref()); - } - - #[test] - fn io_slice_mut_advance_empty_slice() { - let empty_bufs = &mut [][..]; - // Shouldn't panic. - IoSliceMut::advance(empty_bufs, 1); - } - - #[test] - fn io_slice_mut_advance_beyond_total_length() { - let mut buf1 = [1; 8]; - let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; - - // Going beyond the total length should be ok. - bufs = IoSliceMut::advance(bufs, 9); - assert!(bufs.is_empty()); - } - - #[test] - fn io_slice_advance() { - let buf1 = [1; 8]; - let buf2 = [2; 16]; - let buf3 = [3; 8]; - let mut bufs = &mut [IoSlice::new(&buf1), IoSlice::new(&buf2), IoSlice::new(&buf3)][..]; - - // Only in a single buffer.. - bufs = IoSlice::advance(bufs, 1); - assert_eq!(bufs[0].deref(), [1; 7].as_ref()); - assert_eq!(bufs[1].deref(), [2; 16].as_ref()); - assert_eq!(bufs[2].deref(), [3; 8].as_ref()); - - // Removing a buffer, leaving others as is. - bufs = IoSlice::advance(bufs, 7); - assert_eq!(bufs[0].deref(), [2; 16].as_ref()); - assert_eq!(bufs[1].deref(), [3; 8].as_ref()); - - // Removing a buffer and removing from the next buffer. - bufs = IoSlice::advance(bufs, 18); - assert_eq!(bufs[0].deref(), [3; 6].as_ref()); - } - - #[test] - fn io_slice_advance_empty_slice() { - let empty_bufs = &mut [][..]; - // Shouldn't panic. - IoSlice::advance(empty_bufs, 1); - } - - #[test] - fn io_slice_advance_beyond_total_length() { - let buf1 = [1; 8]; - let mut bufs = &mut [IoSlice::new(&buf1)][..]; - - // Going beyond the total length should be ok. - bufs = IoSlice::advance(bufs, 9); - assert!(bufs.is_empty()); - } - - /// Create a new writer that reads from at most `n_bufs` and reads - /// `per_call` bytes (in total) per call to write. - fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter { - TestWriter { n_bufs, per_call, written: Vec::new() } - } - - struct TestWriter { - n_bufs: usize, - per_call: usize, - written: Vec<u8>, - } - - impl Write for TestWriter { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buf)]) - } - - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let mut left = self.per_call; - let mut written = 0; - for buf in bufs.iter().take(self.n_bufs) { - let n = min(left, buf.len()); - self.written.extend_from_slice(&buf[0..n]); - left -= n; - written += n; - } - Ok(written) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } - } - - #[test] - fn test_writer_read_from_one_buf() { - let mut writer = test_writer(1, 2); - - assert_eq!(writer.write(&[]).unwrap(), 0); - assert_eq!(writer.write_vectored(&[]).unwrap(), 0); - - // Read at most 2 bytes. - assert_eq!(writer.write(&[1, 1, 1]).unwrap(), 2); - let bufs = &[IoSlice::new(&[2, 2, 2])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 2); - - // Only read from first buf. - let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4, 4])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 1); - - assert_eq!(writer.written, &[1, 1, 2, 2, 3]); - } - - #[test] - fn test_writer_read_from_multiple_bufs() { - let mut writer = test_writer(3, 3); - - // Read at most 3 bytes from two buffers. - let bufs = &[IoSlice::new(&[1]), IoSlice::new(&[2, 2, 2])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 3); - - // Read at most 3 bytes from three buffers. - let bufs = &[IoSlice::new(&[3]), IoSlice::new(&[4]), IoSlice::new(&[5, 5])]; - assert_eq!(writer.write_vectored(bufs).unwrap(), 3); - - assert_eq!(writer.written, &[1, 2, 2, 3, 4, 5]); - } - - #[test] - fn test_write_all_vectored() { - #[rustfmt::skip] // Becomes unreadable otherwise. - let tests: Vec<(_, &'static [u8])> = vec![ - (vec![], &[]), - (vec![IoSlice::new(&[]), IoSlice::new(&[])], &[]), - (vec![IoSlice::new(&[1])], &[1]), - (vec![IoSlice::new(&[1, 2])], &[1, 2]), - (vec![IoSlice::new(&[1, 2, 3])], &[1, 2, 3]), - (vec![IoSlice::new(&[1, 2, 3, 4])], &[1, 2, 3, 4]), - (vec![IoSlice::new(&[1, 2, 3, 4, 5])], &[1, 2, 3, 4, 5]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2])], &[1, 2]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2])], &[1, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2])], &[1, 1, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2])], &[1, 1, 1, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 2, 2, 2, 2]), - (vec![IoSlice::new(&[1, 1, 1, 1]), IoSlice::new(&[2, 2, 2, 2])], &[1, 1, 1, 1, 2, 2, 2, 2]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2]), IoSlice::new(&[3])], &[1, 2, 3]), - (vec![IoSlice::new(&[1, 1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3])], &[1, 1, 2, 2, 3, 3]), - (vec![IoSlice::new(&[1]), IoSlice::new(&[2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 2, 2, 3, 3, 3]), - (vec![IoSlice::new(&[1, 1, 1]), IoSlice::new(&[2, 2, 2]), IoSlice::new(&[3, 3, 3])], &[1, 1, 1, 2, 2, 2, 3, 3, 3]), - ]; - - let writer_configs = &[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]; - - for (n_bufs, per_call) in writer_configs.iter().copied() { - for (mut input, wanted) in tests.clone().into_iter() { - let mut writer = test_writer(n_bufs, per_call); - assert!(writer.write_all_vectored(&mut *input).is_ok()); - assert_eq!(&*writer.written, &*wanted); - } - } - } -} |
