provola-core 0.2.0

A tool for quick development/test cycle in any language
Documentation
use crate::test_runners::{TestRunner, TestRunnerOpt};
use crate::{Error, Executable, Language, TestResult};
use std::{convert::TryFrom, io::Read, path::PathBuf};

#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, PartialEq, Eq)]
pub struct Source(pub PathBuf);

impl Source {
    pub fn new(path: PathBuf) -> Self {
        Self(path)
    }
}

#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, PartialEq, Eq)]
pub struct TestDataIn(PathBuf);

impl TestDataIn {
    pub fn new(path: PathBuf) -> Self {
        Self(path)
    }
}

impl TryFrom<&TestDataIn> for std::fs::File {
    type Error = Error;

    fn try_from(x: &TestDataIn) -> Result<Self, Self::Error> {
        std::fs::File::open(&x.0).map_err(Error::InvalidInputData)
    }
}

#[derive(serde::Deserialize, serde::Serialize, Clone, Debug, PartialEq, Eq)]
pub struct TestDataOut(PathBuf);

impl TestDataOut {
    pub fn new(path: PathBuf) -> Self {
        Self(path)
    }
}

impl TryFrom<&TestDataOut> for std::fs::File {
    type Error = Error;

    fn try_from(x: &TestDataOut) -> Result<std::fs::File, Self::Error> {
        std::fs::File::open(&x.0).map_err(Error::InvalidOutputData)
    }
}

impl TryFrom<&TestDataOut> for String {
    type Error = Error;

    fn try_from(x: &TestDataOut) -> Result<String, Self::Error> {
        let mut content = String::new();
        let mut file = std::fs::File::try_from(x)?;
        file.read_to_string(&mut content)?;
        Ok(content)
    }
}

pub enum Action {
    BuildTestInputOutput(Language, Source, TestDataIn, TestDataOut),
    TestRunner(Box<dyn TestRunner>, TestRunnerOpt),
}

impl Action {
    pub fn run(&self) -> Result<TestResult, Error> {
        match self {
            Action::BuildTestInputOutput(lang, source, input, output) => {
                let executable = Some(Executable::try_from((*lang, source))?);
                let executable = executable.as_ref().ok_or(Error::NoExecutable)?;
                crate::test::data::test(executable, input, output)
            }

            Action::TestRunner(runner, opt) => runner.run(opt),
        }
    }
}