#temp-dir #directory-structure #directory #sandbox #test-files #json-configuration

rfs_tester

This package allows you to create a temporary directory for testing purposes. You can use it to perform tests related to file operations. After the tests are finished, the temporary directory will be deleted automatically

8 unstable releases (3 breaking)

new 0.4.1 Jan 23, 2025
0.4.0 Jan 23, 2025
0.3.2 Jan 19, 2025
0.2.1 Mar 1, 2021
0.1.6 Feb 27, 2021

#145 in Filesystem

Download history 8/week @ 2024-12-08 294/week @ 2025-01-19

294 downloads per month

MIT license

320KB
732 lines

Rfs_tester

Rfs_tester Logo

Crates.io License

A Rust library for testing file system operations with temporary directories.

Features

  • Create temporary directories and files for testing.
  • Automatically clean up after tests.
  • Flexible configuration using YAML or JSON.

Installation

Add the dependency to your Cargo.toml:

[dependencies]
rfs_tester = "0.4.1"

Overview

This library provides a simple utility for testing file system operations. When you are testing something, you need a sandbox that can be wiped out after the testing is finished. This package allows you to configure a temporary directory and its internal structure, perform tests, and remove it when all the work is done.

It can be configured to generate a customized directory structure. The main idea behind this package is to write test cases for a program that needs to work with the file system, manipulating directories, files, and links to them. The tests require a template directory with several files at various levels of the file system structure.

The random generator is used to add uniqueness to the temporary directory name, which contains other test file system units.

Configuration

The test directory structure can be configured using the YAML or JSON format.

Yaml configuration

---
  - directory:
      name: test
      content:
        - file:
            name: test.txt
            content:
              inline_bytes:
                - 116
                - 101
                - 115
                - 116

It will create a directory named test_726537253725, and a file named test.txt within that directory, which will contain the text "test". The number in the directory name may vary, as it is a random number.

Json configuration

The same directory structure can be configured using JSON format:

[
  {
    "directory":
      {
        "name": "test",
        "content":
          [
            {
              "file":
                {
                  "name": "test.txt",
                  "content":
                    {
                      "inline_bytes": [116,101,115,116]
                    }
                }
            }
          ]
      }
  }
]

Directory configuration

The directory structure can contain many nested directories. However, it is important to note that the first level of the configuration should begin with a single directory. This directory will serve as a sandbox container, with a name that includes a randomly generated number. Other inner components, such as directories, files, and links, should not change their original names and can continue to be used for testing purposes in the configuration.

WARNING!!! Use links with caution, as making changes to the content using a link may modify the original file.

Directory configuration can specify the name and content of:

  • name - string representing the directory name
  • content - a list of internal file system elements (directories, files, links).

Example using the YAML:

---
  - directory:
      name: test
      content:
        - file:
            name: test.txt
            content: empty
        - link:
            name: test_link
            target: test.txt

or the same using the JSON:

{
  "name": "test",
  "content": [
    {
      "file": {
        "name": "test.txt",
        "content": "empty"
      }
    },
    {
      "link": {
        "name": "test_link",
        "target": "test.txt"
      }
    }
  ]
}

How to Define a Test?

When we want to test files, directories, and links in the created sandbox, we need to know the exact name of the outer directory. This name will be unique each time FsTester creates it. FsTester provides us with this name as a closure parameter in the perform_fs_test function.

Example:

#[cfg(test)]
mod tests {
  use std::fs;
  use rfs_tester::{FsTester, FileContent};
  use rfs_tester::config::{Configuration, ConfigEntry, DirectoryConf, FileConf};

  #[test]
  fn test_file_creation() {
    const YAML_DIR_WITH_TEST_FILE_FROM_CARGO_TOML: &str = "---
    - directory:
        name: test
        content:
          - file:
              name: test_from_cargo.toml
              content:
                original_file: Cargo.toml
     ";

    let tester = FsTester::new(YAML_DIR_WITH_TEST_FILE_FROM_CARGO_TOML, ".").expect("Incorrect configuration");
    tester.perform_fs_test(|dirname| {
    //                      ^^^^^^^ name with a random number at the end
      let inner_file_name = format!("{}/{}", dirname, "test_from_cargo.toml");
      let metadata = fs::metadata(inner_file_name)?;

      assert!(metadata.len() > 0);
      Ok(())
    });
  }
}

Examples

Basic Usage with macro rfs_test_macro from rfs_test_macro crate

use rfs_test_macro::rfs_test;

#[rfs_test(
    config = r#"---
    - !directory
        name: test
        content:
          - !file
              name: test.txt
              content:
                !inline_text "Hello, world!"
    "#,
    start_point = "."
)]
fn file_creation_test(dirname: &str) -> std::io::Result<()> {
    let file_path = format!("{}/test.txt", dirname);
    let content = std::fs::read_to_string(file_path)?;
    assert_eq!(content, "Hello, world!");
    Ok(())
}

Add dependency in Cargo.toml to use it:

[dependencies]
rfs_test_macro = "1.1.0"

Using JSON Configuration

use rfs_tester::{FsTester, FileContent};
use rfs_tester::config::{Configuration, ConfigEntry, DirectoryConf, FileConf};

#[test]
fn test_file_creation() {
    const JSON_CONFIG: &str = r#"
    [
      {
        "directory": {
          "name": "test",
          "content": [
            {
              "file": {
                "name": "test.txt",
                "content": {
                  "inline_bytes": [116, 101, 115, 116]
                }
              }
            }
          ]
        }
      }
    ]
    "#;

    let tester = FsTester::new(JSON_CONFIG, ".").expect("Incorrect configuration");;
    tester.perform_fs_test(|dirname| {
        let file_path = format!("{}/test.txt", dirname);
        let content = std::fs::read_to_string(file_path)?;
        assert_eq!(content, "test");
        Ok(())
    });
}

Contributing

Contributions are welcome! If you'd like to contribute, please follow these steps:

  1. Fork the repository.
  2. Create a new branch for your feature or bugfix.
  3. Make your changes and ensure all tests pass.
  4. Submit a pull request with a detailed description of your changes.

Licenses

This project is licensed under the MIT or Apache-2.0 License.

Dependencies

~2.4–3.5MB
~73K SLoC