diskit 0.1.5

Utilities for intercepting disk requests.
Documentation
use std::{
    env::current_dir,
    io::{Read, Seek, SeekFrom, Write},
};

use walkdir::WalkDir;

use crate::{
    dir_entry::DirEntry,
    diskit_extend::DiskitExt,
    metadata::{FileType, Metadata},
    VirtualDiskit,
};

#[test]
fn read_write()
{
    let diskit = VirtualDiskit::default();

    // Creating

    let mut file1 = diskit.create("test.txt").unwrap();

    file1.write_all(b"Hello, World!").unwrap();

    file1.flush().unwrap();

    // Reading normally to string

    let mut file2 = diskit.open("test.txt").unwrap();

    let mut buf = String::new();

    file2.read_to_string(&mut buf).unwrap();

    assert_eq!(buf, "Hello, World!");

    // Closing

    file1.close().unwrap();

    file2.close().unwrap();

    // Reading partially to vec

    let mut file3 = diskit.open("test.txt").unwrap();

    file3.seek(SeekFrom::End(-6)).unwrap();

    let mut buf = vec![];

    file3.read_to_end(&mut buf).unwrap();

    assert_eq!(buf, b"World!");
}

// Most of the lines in this function are just data and add no mental
// complexity to it, therefore this is a false positive here.
#[allow(clippy::too_many_lines)]
#[test]
fn walkdir()
{
    let diskit = VirtualDiskit::default();

    // Creating

    diskit.create_dir_all("abc/def/ghi/jkl").unwrap();

    diskit.set_pwd("/abc").unwrap();

    let mut file = diskit.create("def/qwe.txt").unwrap();
    file.write_all(b"Hello, World!\n").unwrap();

    // Reading

    let mut files_directory_first = vec![];
    let mut files_content_first = vec![];

    for file in diskit.walkdir(".")
    {
        files_directory_first.push(file.unwrap());
    }
    for file in diskit.walkdir(".").set_contents_first(true)
    {
        files_content_first.push(file.unwrap());
    }

    assert_ne!(files_directory_first, files_content_first);

    files_directory_first.sort();
    files_content_first.sort();

    // Checking

    assert_eq!(
        files_directory_first,
        [
            DirEntry {
                path: ".".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 0,
                ino: 1,
            },
            DirEntry {
                path: "./def".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 1,
                ino: 2,
            },
            DirEntry {
                path: "./def/ghi".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 2,
                ino: 3,
            },
            DirEntry {
                path: "./def/ghi/jkl".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 3,
                ino: 4,
            },
            DirEntry {
                path: "./def/qwe.txt".into(),
                metadata: Metadata {
                    file_type: FileType::File,
                    len: 14,
                },
                follow_link: false,
                depth: 2,
                ino: 5,
            },
        ]
    );

    assert_eq!(
        files_content_first,
        [
            DirEntry {
                path: ".".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 0,
                ino: 1,
            },
            DirEntry {
                path: "./def".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 1,
                ino: 2,
            },
            DirEntry {
                path: "./def/ghi".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 2,
                ino: 3,
            },
            DirEntry {
                path: "./def/ghi/jkl".into(),
                metadata: Metadata {
                    file_type: FileType::Dir,
                    len: 0,
                },
                follow_link: false,
                depth: 3,
                ino: 4,
            },
            DirEntry {
                path: "./def/qwe.txt".into(),
                metadata: Metadata {
                    file_type: FileType::File,
                    len: 14,
                },
                follow_link: false,
                depth: 2,
                ino: 5,
            },
        ]
    );
}

#[test]
fn dynamic_walkdir_test()
{
    let diskit = VirtualDiskit::default();
    let current_dir = current_dir().unwrap();

    diskit.create_dir_all(&current_dir).unwrap();

    for file in WalkDir::new(&current_dir)
        .sort_by_file_name()
        .into_iter()
        .skip(1)
    {
        let file = file.unwrap();
        if file.metadata().unwrap().is_dir()
        {
            diskit.create_dir(file.path()).unwrap();
        }
        else
        {
            diskit.create(file.path()).unwrap();
        }
    }

    let mut diskits_output = diskit
        .walkdir(&current_dir)
        .into_iter()
        .map(Result::unwrap)
        .map(|x| (x.path().to_owned(), x.metadata().is_file()))
        .collect::<Vec<_>>();
    let mut walkdirs_output = WalkDir::new(&current_dir)
        .into_iter()
        .map(Result::unwrap)
        .map(|x| (x.path().to_owned(), !x.metadata().unwrap().is_dir()))
        .collect::<Vec<_>>();

    diskits_output.sort();
    walkdirs_output.sort();

    assert_eq!(diskits_output, walkdirs_output);
}

#[cfg(feature = "trash")]
#[test]
fn trash()
{
    let diskit = VirtualDiskit::default();

    diskit.create_dir_all("abc").unwrap();

    let mut a = diskit.create("abc/d1").unwrap();
    let mut b = diskit.create("abc/e2").unwrap();
    diskit.create("abc/f3").unwrap();
    diskit.create("abc/g4").unwrap();

    writeln!(a, "ABC").unwrap();
    writeln!(b, "DEF").unwrap();

    drop(a);
    drop(b);

    diskit.trash_delete("abc/d1").unwrap();
    diskit.trash_delete("abc/f3").unwrap();

    diskit.read_to_string("abc/d1").unwrap_err();
    assert_eq!(diskit.read_to_string("abc/e2").unwrap(), "DEF\n");

    diskit.open("abc/f3").unwrap_err();
    diskit.open("abc/g4").unwrap();
}