kxio 1.1.2

Provides injectable Filesystem and Network resources to make code more testable
Documentation
use assert2::let_assert;

use crate::fs;

type TestResult = Result<(), fs::Error>;

mod path_of {
    use super::*;
    #[test]
    fn validate_fails_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;

        let_assert!(Err(fs::Error::PathTraversal { base, path: _path }) = fs.path_of("..".into()));
        assert_eq!(base, fs.base());

        Ok(())
    }
}

mod file {
    use super::*;
    #[test]
    /// Write to a file, read it, verify it exists, is a file and has the expected contents
    fn write_read_file_exists() -> TestResult {
        let fs = fs::temp()?;
        let pathbuf = fs.base().join("foo");

        let_assert!(Ok(_) = fs.file_write(&pathbuf, "content"));
        let_assert!(
            Ok(c) = fs.file_read_to_string(&pathbuf),
            "file_read_to_string"
        );
        assert_eq!(c, "content");

        let_assert!(Ok(exists) = fs.path_exists(&pathbuf));
        assert!(exists);

        let_assert!(Ok(is_file) = fs.path_is_file(&pathbuf));
        assert!(is_file);

        Ok(())
    }
}

mod dir_create {
    use super::*;
    #[test]
    fn should_create_a_dir() -> TestResult {
        let fs = fs::temp()?;
        let pathbuf = fs.base().join("subdir");

        let_assert!(Ok(_) = fs.dir_create(&pathbuf));

        let_assert!(Ok(exists) = fs.path_exists(&pathbuf));
        assert!(exists);

        let_assert!(Ok(is_dir) = fs.path_is_dir(&pathbuf));
        assert!(is_dir);

        Ok(())
    }
    #[test]
    fn should_fail_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("..").join("foo");
        let_assert!(
            Err(fs::Error::PathTraversal {
                base: _base,
                path: _path
            }) = fs.dir_create(&path)
        );

        Ok(())
    }
}

mod dir_create_all {
    use super::*;

    #[test]
    fn should_create_a_dir() -> TestResult {
        let fs = fs::temp()?;
        let pathbuf = fs.base().join("subdir").join("child");

        let_assert!(Ok(_) = fs.dir_create_all(&pathbuf));

        let_assert!(Ok(exists) = fs.path_exists(&pathbuf));
        assert!(exists, "path exists");

        let_assert!(Ok(is_dir) = fs.path_is_dir(&pathbuf));
        assert!(is_dir, "path is a directory");

        Ok(())
    }
    #[test]
    fn should_fail_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("..").join("foo");
        let_assert!(
            Err(fs::Error::PathTraversal {
                base: _base,
                path: _path
            }) = fs.dir_create_all(&path)
        );

        Ok(())
    }
}

mod path_exists {
    use super::*;
    #[test]
    fn should_be_true_when_it_exists() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(_) = fs.file_write(&path, "bar"));
        let_assert!(Ok(exists) = fs.path_exists(&path));
        assert!(exists);

        Ok(())
    }
    #[test]
    fn should_be_false_when_it_does_not_exist() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(exists) = fs.path_exists(&path));
        assert!(!exists);

        Ok(())
    }
    #[test]
    fn should_fail_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("..").join("foo");
        let_assert!(
            Err(fs::Error::PathTraversal {
                base: _base,
                path: _path
            }) = fs.path_exists(&path)
        );

        Ok(())
    }
}

mod path_is_dir {
    use super::*;
    #[test]
    fn should_be_true_when_is_a_dir() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(_) = fs.dir_create(&path));
        let_assert!(Ok(is_dir) = fs.path_is_dir(&path));
        assert!(is_dir);

        Ok(())
    }
    #[test]
    fn should_be_false_when_is_a_file() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(_) = fs.file_write(&path, "bar"));
        let_assert!(Ok(is_dir) = fs.path_is_dir(&path));
        assert!(!is_dir);

        Ok(())
    }
    #[test]
    #[ignore]
    fn should_be_false_when_is_a_link() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        // TODO create a link
        // let_assert!(Ok(_) = fs.file_write(&path, "bar"));
        let_assert!(Ok(is_dir) = fs.path_is_dir(&path));
        assert!(!is_dir);

        Ok(())
    }
    #[test]
    fn should_fail_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("..").join("foo");
        let_assert!(
            Err(fs::Error::PathTraversal {
                base: _base,
                path: _path
            }) = fs.path_is_dir(&path)
        );

        Ok(())
    }
}

mod path_is_file {
    use super::*;
    #[test]
    fn should_be_true_when_is_a_file() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(_) = fs.file_write(&path, "bar"));

        let_assert!(Ok(is_file) = fs.path_is_file(&path));
        assert!(is_file);

        Ok(())
    }
    #[test]
    fn should_be_false_when_is_a_dir() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        let_assert!(Ok(_) = fs.dir_create(&path));
        let_assert!(Ok(is_file) = fs.path_is_file(&path));
        assert!(!is_file);

        Ok(())
    }
    #[test]
    #[ignore]
    fn should_be_false_when_is_a_link() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("foo");
        // TODO create a link
        // let_assert!(Ok(_) = fs.file_write(&path, "bar"));
        let_assert!(Ok(is_file) = fs.path_is_file(&path));
        assert!(!is_file);

        Ok(())
    }
    #[test]
    fn should_fail_on_path_traversal() -> TestResult {
        let fs = fs::temp()?;
        let path = fs.base().join("..").join("foo");
        let_assert!(
            Err(fs::Error::PathTraversal {
                base: _base,
                path: _path
            }) = fs.path_is_file(&path)
        );

        Ok(())
    }
}