Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli-test: Add easy file creation syntax
Alexis Sellier committed 2 years ago
commit d4e073fe4e8de49462b54b7d3b15bec0140b94dc
parent e7006080955f069d23f86888ac02f092e90405c5
1 file changed +29 -3
modified radicle-cli-test/src/lib.rs
@@ -2,6 +2,7 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
+
use std::str::FromStr;
use std::sync;
use std::{env, ffi, fs, io, mem};

@@ -16,6 +17,8 @@ static BUILD: sync::Once = sync::Once::new();
pub enum Error {
    #[error("parsing failed")]
    Parse,
+
    #[error("invalid file path: {0:?}")]
+
    InvalidFilePath(String),
    #[error("test file not found: {0:?}")]
    TestNotFound(PathBuf),
    #[error("i/o: {0}")]
@@ -172,14 +175,27 @@ impl TestFormula {
    pub fn read(&mut self, path: &Path, r: impl io::BufRead) -> Result<&mut Self, Error> {
        let mut test = Test::default();
        let mut fenced = false; // Whether we're inside a fenced code block.
+
        let mut file: Option<(PathBuf, String)> = None; // Path and content of file created by this test block.

        for line in r.lines() {
            let line = line?;

            if line.starts_with("```") {
                if fenced {
-
                    // End existing code block.
-
                    self.tests.push(mem::take(&mut test));
+
                    if let Some((ref path, ref mut content)) = file.take() {
+
                        // Write file.
+
                        let path = self.cwd.join(path);
+

+
                        if let Some(dir) = path.parent() {
+
                            log::debug!(target: "test", "Creating directory {}..", dir.display());
+
                            fs::create_dir_all(dir)?;
+
                        }
+
                        log::debug!(target: "test", "Writing {} bytes to {}..", content.len(), path.display());
+
                        fs::write(path, content)?;
+
                    } else {
+
                        // End existing code block.
+
                        self.tests.push(mem::take(&mut test));
+
                    }
                } else {
                    for token in line.split_whitespace() {
                        if token.contains("stderr") {
@@ -188,6 +204,13 @@ impl TestFormula {
                        if token.contains("fail") {
                            test.fail = true;
                        }
+
                        if let Some(path) = token.strip_prefix("./") {
+
                            file = Some((
+
                                PathBuf::from_str(path)
+
                                    .map_err(|_| Error::InvalidFilePath(token.to_owned()))?,
+
                                String::new(),
+
                            ));
+
                        }
                        if let Some((key, val)) = token.split_once('=') {
                            test.env.insert(key.to_owned(), val.to_owned());
                        }
@@ -199,7 +222,10 @@ impl TestFormula {
            }

            if fenced {
-
                if let Some(line) = line.strip_prefix('$') {
+
                if let Some((_, ref mut content)) = file {
+
                    content.push_str(line.as_str());
+
                    content.push('\n');
+
                } else if let Some(line) = line.strip_prefix('$') {
                    let line = line.trim();
                    let parts = shlex::split(line).ok_or(Error::Parse)?;
                    let (cmd, args) = parts.split_first().ok_or(Error::Parse)?;