1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use chrono::{DateTime, TimeZone};
use std::fs::File;
use std::path::Path;

/// A loaded fixture file.
pub struct FixtureFile<Tz: TimeZone + Send + Sync> {
    pub path: String,
    pub file_name: String,
    pub content: File,
    pub insert_sqls: Vec<InsertSql<Tz>>,
}

/// SQL query and parameters.
pub struct InsertSql<Tz: TimeZone + Send + Sync> {
    pub sql: String,
    pub params: Vec<SqlParam<Tz>>,
}

/// SQL parameter types.
pub enum SqlParam<Tz>
where
    Tz: TimeZone + Send + Sync,
{
    String(String),
    Datetime(DateTime<Tz>),
    Integer(u32),
    Float(f32),
    Boolean(bool),
}

impl<Tz> FixtureFile<Tz>
where
    Tz: TimeZone + Send + Sync,
{
    pub(crate) fn file_stem(&self) -> String {
        Path::new(self.file_name.as_str())
            .file_stem()
            .unwrap()
            .to_str()
            .unwrap()
            .to_string()
    }

    pub(crate) fn delete(&self) -> String {
        format!("DELETE FROM {}", self.file_stem())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use chrono::Utc;
    use std::fs::File;
    use std::io::Write;
    use tempfile::tempdir;

    #[test]
    fn test_file_stem() -> anyhow::Result<()> {
        let dir = tempdir()?;
        let file_path = dir.path().join("todos.yml");
        let fixture_file_path = file_path.clone();
        let mut file = File::create(file_path)?;
        writeln!(
            file,
            r#"
        - id: 1
          description: fizz
          created_at: 2020/01/01 01:01:01
          updated_at: RAW=NOW()"#
        )
        .unwrap();

        let fixture_file = FixtureFile::<Utc> {
            path: fixture_file_path.to_str().unwrap().to_string(),
            file_name: fixture_file_path
                .clone()
                .file_name()
                .unwrap()
                .to_str()
                .unwrap()
                .to_string(),
            content: File::open(fixture_file_path.clone()).unwrap(),
            insert_sqls: vec![],
        };

        assert_eq!(fixture_file.file_stem(), "todos");
        Ok(())
    }

    #[test]
    fn test_delete() -> anyhow::Result<()> {
        let dir = tempdir()?;
        let file_path = dir.path().join("todos.yml");
        let fixture_file_path = file_path.clone();
        let mut file = File::create(file_path)?;
        writeln!(
            file,
            r#"
        - id: 1
          description: fizz
          created_at: 2020/01/01 01:01:01
          updated_at: RAW=NOW()"#
        )
        .unwrap();

        let fixture_file = FixtureFile::<Utc> {
            path: fixture_file_path.to_str().unwrap().to_string(),
            file_name: fixture_file_path
                .clone()
                .file_name()
                .unwrap()
                .to_str()
                .unwrap()
                .to_string(),
            content: File::open(fixture_file_path.clone()).unwrap(),
            insert_sqls: vec![],
        };

        assert_eq!(fixture_file.delete(), "DELETE FROM todos");
        Ok(())
    }
}