src/source/file/seek_test.rs

#[cfg(test)]
mod tests {
    use std::io::Write;

    use tempfile::NamedTempFile;
    use tokio::fs::File;

    use crate::source::file::seek::from_end;

    async fn open(body: &[u8]) -> (File, NamedTempFile) {
        let mut tmp = NamedTempFile::new().unwrap();
        tmp.write_all(body).unwrap();
        tmp.flush().unwrap();
        let file = File::open(tmp.path()).await.unwrap();
        (file, tmp)
    }

    #[tokio::test]
    async fn zero_lines_seeks_to_end() {
        let (mut f, _g) = open(b"alpha\nbeta\ngamma\n").await;
        let off = from_end(&mut f, 0).await.unwrap();
        assert_eq!(off, 17);
    }

    #[tokio::test]
    async fn single_line_from_end() {
        let (mut f, _g) = open(b"alpha\nbeta\ngamma\n").await;
        let off = from_end(&mut f, 1).await.unwrap();
        assert_eq!(off, 11);
    }

    #[tokio::test]
    async fn more_lines_than_file_has_returns_zero() {
        let (mut f, _g) = open(b"alpha\nbeta\n").await;
        let off = from_end(&mut f, 100).await.unwrap();
        assert_eq!(off, 0);
    }

    #[tokio::test]
    async fn no_trailing_newline_works() {
        let (mut f, _g) = open(b"alpha\nbeta\ngamma").await;
        let off = from_end(&mut f, 1).await.unwrap();
        assert_eq!(off, 11);
    }

    #[tokio::test]
    async fn across_chunk_boundaries() {
        let mut body = Vec::new();
        for i in 0..5000 {
            body.extend_from_slice(format!("line {}\n", i).as_bytes());
        }
        let (mut f, _g) = open(&body).await;
        let off = from_end(&mut f, 1).await.unwrap();
        let tail = &body[off as usize..];
        assert_eq!(tail, b"line 4999\n");
    }

    #[tokio::test]
    async fn empty_file_returns_zero() {
        let (mut f, _g) = open(b"").await;
        let off = from_end(&mut f, 5).await.unwrap();
        assert_eq!(off, 0);
    }

    #[tokio::test]
    async fn single_byte_non_newline() {
        let (mut f, _g) = open(b"x").await;
        let off = from_end(&mut f, 1).await.unwrap();
        assert_eq!(off, 0);
    }
}