Skip to content

Commit 46d98f0

Browse files
committed
Add test for list returning unix newlines
* Split implementation of `list_command` into the new `get_lines_from_stream` fn in order to make it easier to test * Add two tests `get_lines_from_stream` for dos and unix newlines
1 parent b7b14d4 commit 46d98f0

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ chrono = "0.4.11"
2929
tokio = { version = "0.2.21", features = ["tcp", "dns", "io-util"] }
3030
tokio-rustls = { version = "0.13.1", optional = true }
3131
pin-project = "0.4.17"
32+
33+
[dev-dependencies.tokio]
34+
version = "0.2.21"
35+
features = [ "macros", "stream", "io-util" ]

src/ftp.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use chrono::{DateTime, Utc};
99
use regex::Regex;
1010

1111
use tokio::io::{
12-
copy, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter,
12+
copy, AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWriteExt, BufReader,
13+
BufWriter,
1314
};
1415
use tokio::net::{TcpStream, ToSocketAddrs};
1516

@@ -435,12 +436,20 @@ impl FtpStream {
435436
open_code: u32,
436437
close_code: &[u32],
437438
) -> Result<Vec<String>> {
438-
let mut lines: Vec<String> = Vec::new();
439-
440-
let mut data_stream = BufReader::new(self.data_command(&cmd).await?);
439+
let data_stream = BufReader::new(self.data_command(&cmd).await?);
441440
self.read_response_in(&[open_code, status::ALREADY_OPEN])
442441
.await?;
442+
let lines = Self::get_lines_from_stream(data_stream).await?;
443+
self.read_response_in(close_code).await?;
444+
Ok(lines)
445+
}
443446

447+
/// Consume a stream and return a vector of lines
448+
async fn get_lines_from_stream<R>(mut data_stream: R) -> Result<Vec<String>>
449+
where
450+
R: AsyncBufRead + Unpin,
451+
{
452+
let mut lines: Vec<String> = Vec::new();
444453
let mut line = String::new();
445454
loop {
446455
match data_stream.read_to_string(&mut line).await {
@@ -453,9 +462,6 @@ impl FtpStream {
453462
Err(err) => return Err(FtpError::ConnectionError(err)),
454463
};
455464
}
456-
drop(data_stream);
457-
458-
self.read_response_in(close_code).await?;
459465
Ok(lines)
460466
}
461467

@@ -597,3 +603,37 @@ impl FtpStream {
597603
}
598604
}
599605
}
606+
607+
#[cfg(test)]
608+
mod tests {
609+
use super::FtpStream;
610+
use tokio::{io::stream_reader, stream};
611+
612+
#[tokio::test]
613+
async fn list_command_dos_newlines() {
614+
let data_stream = stream_reader(stream::once(Ok(
615+
b"Hello\r\nWorld\r\n\r\nBe\r\nHappy\r\n" as &[u8]
616+
)));
617+
618+
assert_eq!(
619+
FtpStream::get_lines_from_stream(data_stream).await.unwrap(),
620+
["Hello", "World", "Be", "Happy"]
621+
.iter()
622+
.map(<&str>::to_string)
623+
.collect::<Vec<_>>()
624+
);
625+
}
626+
627+
#[tokio::test]
628+
async fn list_command_unix_newlines() {
629+
let data_stream = stream_reader(stream::once(Ok(b"Hello\nWorld\n\nBe\nHappy\n" as &[u8])));
630+
631+
assert_eq!(
632+
FtpStream::get_lines_from_stream(data_stream).await.unwrap(),
633+
["Hello", "World", "Be", "Happy"]
634+
.iter()
635+
.map(<&str>::to_string)
636+
.collect::<Vec<_>>()
637+
);
638+
}
639+
}

0 commit comments

Comments
 (0)