diff options
| author | Federico Igne <git@federicoigne.com> | 2020-12-26 17:48:38 +0000 |
|---|---|---|
| committer | Federico Igne <git@federicoigne.com> | 2021-11-03 18:55:08 +0000 |
| commit | 02481656966b0a8dfc95cf3c22bcc049660ff7d4 (patch) | |
| tree | 8e39798fcaf27931d91c2088423fd4e97adcfc2d /rust/paasio/tests/paasio.rs | |
| parent | 4e2052c4d792540c2f742b2c2a081b11117ed41d (diff) | |
| download | exercism-02481656966b0a8dfc95cf3c22bcc049660ff7d4.tar.gz exercism-02481656966b0a8dfc95cf3c22bcc049660ff7d4.zip | |
Move Rust exercises in a subdirectory
Diffstat (limited to 'rust/paasio/tests/paasio.rs')
| -rw-r--r-- | rust/paasio/tests/paasio.rs | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/rust/paasio/tests/paasio.rs b/rust/paasio/tests/paasio.rs new file mode 100644 index 0000000..6b44199 --- /dev/null +++ b/rust/paasio/tests/paasio.rs | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | /// test a few read scenarios | ||
| 2 | macro_rules! test_read { | ||
| 3 | ($(#[$attr:meta])* $modname:ident ($input:expr, $len:expr)) => { | ||
| 4 | mod $modname { | ||
| 5 | use std::io::{Read, BufReader}; | ||
| 6 | use paasio::*; | ||
| 7 | |||
| 8 | const CHUNK_SIZE: usize = 2; | ||
| 9 | |||
| 10 | $(#[$attr])* | ||
| 11 | #[test] | ||
| 12 | fn test_read_passthrough() { | ||
| 13 | let data = $input; | ||
| 14 | let size = $len(&data); | ||
| 15 | let mut reader = ReadStats::new(data); | ||
| 16 | |||
| 17 | let mut buffer = Vec::with_capacity(size); | ||
| 18 | let qty_read = reader.read_to_end(&mut buffer); | ||
| 19 | |||
| 20 | assert!(qty_read.is_ok()); | ||
| 21 | assert_eq!(size, qty_read.unwrap()); | ||
| 22 | assert_eq!(size, buffer.len()); | ||
| 23 | // 2: first to read all the data, second to check that | ||
| 24 | // there wasn't any more pending data which simply didn't | ||
| 25 | // fit into the existing buffer | ||
| 26 | assert_eq!(2, reader.reads()); | ||
| 27 | assert_eq!(size, reader.bytes_through()); | ||
| 28 | } | ||
| 29 | |||
| 30 | $(#[$attr])* | ||
| 31 | #[test] | ||
| 32 | fn test_read_chunks() { | ||
| 33 | let data = $input; | ||
| 34 | let size = $len(&data); | ||
| 35 | let mut reader = ReadStats::new(data); | ||
| 36 | |||
| 37 | let mut buffer = [0_u8; CHUNK_SIZE]; | ||
| 38 | let mut chunks_read = 0; | ||
| 39 | while reader.read(&mut buffer[..]).unwrap_or_else(|_| panic!("read failed at chunk {}", chunks_read+1)) > 0 { | ||
| 40 | chunks_read += 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | assert_eq!(size / CHUNK_SIZE + std::cmp::min(1, size % CHUNK_SIZE), chunks_read); | ||
| 44 | // we read once more than the number of chunks, because the final | ||
| 45 | // read returns 0 new bytes | ||
| 46 | assert_eq!(1+chunks_read, reader.reads()); | ||
| 47 | assert_eq!(size, reader.bytes_through()); | ||
| 48 | } | ||
| 49 | |||
| 50 | $(#[$attr])* | ||
| 51 | #[test] | ||
| 52 | fn test_read_buffered_chunks() { | ||
| 53 | let data = $input; | ||
| 54 | let size = $len(&data); | ||
| 55 | let mut reader = BufReader::new(ReadStats::new(data)); | ||
| 56 | |||
| 57 | let mut buffer = [0_u8; CHUNK_SIZE]; | ||
| 58 | let mut chunks_read = 0; | ||
| 59 | while reader.read(&mut buffer[..]).unwrap_or_else(|_| panic!("read failed at chunk {}", chunks_read+1)) > 0 { | ||
| 60 | chunks_read += 1; | ||
| 61 | } | ||
| 62 | |||
| 63 | assert_eq!(size / CHUNK_SIZE + std::cmp::min(1, size % CHUNK_SIZE), chunks_read); | ||
| 64 | // the BufReader should smooth out the reads, collecting into | ||
| 65 | // a buffer and performing only two read operations: | ||
| 66 | // the first collects everything into the buffer, | ||
| 67 | // and the second ensures that no data remains | ||
| 68 | assert_eq!(2, reader.get_ref().reads()); | ||
| 69 | assert_eq!(size, reader.get_ref().bytes_through()); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | }; | ||
| 73 | } | ||
| 74 | |||
| 75 | /// test a few write scenarios | ||
| 76 | macro_rules! test_write { | ||
| 77 | ($(#[$attr:meta])* $modname:ident ($input:expr, $len:expr)) => { | ||
| 78 | mod $modname { | ||
| 79 | use std::io::{self, Write, BufWriter}; | ||
| 80 | use paasio::*; | ||
| 81 | |||
| 82 | const CHUNK_SIZE: usize = 2; | ||
| 83 | $(#[$attr])* | ||
| 84 | #[test] | ||
| 85 | fn test_write_passthrough() { | ||
| 86 | let data = $input; | ||
| 87 | let size = $len(&data); | ||
| 88 | let mut writer = WriteStats::new(Vec::with_capacity(size)); | ||
| 89 | let written = writer.write(data); | ||
| 90 | assert!(written.is_ok()); | ||
| 91 | assert_eq!(size, written.unwrap()); | ||
| 92 | assert_eq!(size, writer.bytes_through()); | ||
| 93 | assert_eq!(1, writer.writes()); | ||
| 94 | assert_eq!(data, writer.get_ref().as_slice()); | ||
| 95 | } | ||
| 96 | |||
| 97 | $(#[$attr])* | ||
| 98 | #[test] | ||
| 99 | fn test_sink_oneshot() { | ||
| 100 | let data = $input; | ||
| 101 | let size = $len(&data); | ||
| 102 | let mut writer = WriteStats::new(io::sink()); | ||
| 103 | let written = writer.write(data); | ||
| 104 | assert!(written.is_ok()); | ||
| 105 | assert_eq!(size, written.unwrap()); | ||
| 106 | assert_eq!(size, writer.bytes_through()); | ||
| 107 | assert_eq!(1, writer.writes()); | ||
| 108 | } | ||
| 109 | |||
| 110 | $(#[$attr])* | ||
| 111 | #[test] | ||
| 112 | fn test_sink_windowed() { | ||
| 113 | let data = $input; | ||
| 114 | let size = $len(&data); | ||
| 115 | let mut writer = WriteStats::new(io::sink()); | ||
| 116 | |||
| 117 | let mut chunk_count = 0; | ||
| 118 | for chunk in data.chunks(CHUNK_SIZE) { | ||
| 119 | chunk_count += 1; | ||
| 120 | let written = writer.write(chunk); | ||
| 121 | assert!(written.is_ok()); | ||
| 122 | assert_eq!(CHUNK_SIZE, written.unwrap()); | ||
| 123 | } | ||
| 124 | assert_eq!(size, writer.bytes_through()); | ||
| 125 | assert_eq!(chunk_count, writer.writes()); | ||
| 126 | } | ||
| 127 | |||
| 128 | $(#[$attr])* | ||
| 129 | #[test] | ||
| 130 | fn test_sink_buffered_windowed() { | ||
| 131 | let data = $input; | ||
| 132 | let size = $len(&data); | ||
| 133 | let mut writer = BufWriter::new(WriteStats::new(io::sink())); | ||
| 134 | |||
| 135 | for chunk in data.chunks(CHUNK_SIZE) { | ||
| 136 | let written = writer.write(chunk); | ||
| 137 | assert!(written.is_ok()); | ||
| 138 | assert_eq!(CHUNK_SIZE, written.unwrap()); | ||
| 139 | } | ||
| 140 | // at this point, nothing should have yet been passed through to | ||
| 141 | // our writer | ||
| 142 | assert_eq!(0, writer.get_ref().bytes_through()); | ||
| 143 | assert_eq!(0, writer.get_ref().writes()); | ||
| 144 | |||
| 145 | // after flushing, everything should pass through in one go | ||
| 146 | assert!(writer.flush().is_ok()); | ||
| 147 | assert_eq!(size, writer.get_ref().bytes_through()); | ||
| 148 | assert_eq!(1, writer.get_ref().writes()); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | }; | ||
| 152 | } | ||
| 153 | |||
| 154 | #[test] | ||
| 155 | fn test_create_stats() { | ||
| 156 | let mut data: Vec<u8> = Vec::new(); | ||
| 157 | let _ = paasio::ReadStats::new(data.as_slice()); | ||
| 158 | let _ = paasio::WriteStats::new(data.as_mut_slice()); | ||
| 159 | } | ||
| 160 | |||
| 161 | test_read!(read_string ( | ||
| 162 | "Twas brillig, and the slithy toves/Did gyre and gimble in the wabe:/All mimsy were the borogoves,/And the mome raths outgrabe.".as_bytes(), | ||
| 163 | |d: &[u8]| d.len() | ||
| 164 | )); | ||
| 165 | test_write!(write_string ( | ||
| 166 | "Beware the Jabberwock, my son!/The jaws that bite, the claws that catch!/Beware the Jubjub bird, and shun/The frumious Bandersnatch!".as_bytes(), | ||
| 167 | |d: &[u8]| d.len() | ||
| 168 | )); | ||
| 169 | |||
| 170 | test_read!(read_byte_literal( | ||
| 171 | &[1_u8, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144][..], | ||
| 172 | |d: &[u8]| d.len() | ||
| 173 | )); | ||
| 174 | test_write!(write_byte_literal( | ||
| 175 | &[2_u8, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,][..], | ||
| 176 | |d: &[u8]| d.len() | ||
| 177 | )); | ||
| 178 | |||
| 179 | test_read!(read_file( | ||
| 180 | ::std::fs::File::open("README.md").expect("readme must be present"), | ||
| 181 | |f: &::std::fs::File| f.metadata().expect("metadata must be present").len() as usize | ||
| 182 | )); | ||
| 183 | |||
| 184 | #[test] | ||
| 185 | fn read_stats_by_ref_returns_wrapped_reader() { | ||
| 186 | use paasio::ReadStats; | ||
| 187 | |||
| 188 | let input = | ||
| 189 | "Why, sometimes I've believed as many as six impossible things before breakfast".as_bytes(); | ||
| 190 | let reader = ReadStats::new(input); | ||
| 191 | assert_eq!(reader.get_ref(), &input); | ||
| 192 | } | ||
