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
use failure::err_msg;
use failure::Error;
use serde;
use serde_json;
use sorted_json::to_json;
use std::{
    collections::HashMap,
    env,
    fs::File,
    io::{Read, Write},
    path::PathBuf,
    process::Command,
    string::String,
};
// ours
use destination;
use function;
use scrub;

pub fn assert_snapshot_2<T>(
    file: &'static str,
    line: u32,
    extra: &str,
    data: &T,
) -> Result<(), Error>
where
    T: serde::Serialize,
{
    assert_snapshot_(file, line, extra, data, &HashMap::new())
}

pub fn assert_snapshot_<T>(
    file: &'static str,
    line: u32,
    extra: &str,
    data: &T,
    scrubs: &HashMap<String, String>,
) -> Result<(), Error>
where
    T: serde::Serialize,
{
    let new_content = serde_json::to_value(data)?;
    let mut new_content = to_json(&new_content);
    let mut ext = "json";
    if let serde_json::Value::String(s) = serde_json::to_value(data)? {
        new_content = s;
        ext = "txt";
    }
    let new_content = new_content + "\n";
    let new_content = scrub::scrub(&new_content, scrubs);

    let func = function::function(file, line);
    // see if a file exits in test folder(=> next to src), if so we compare the output with that
    // else we create the file
    let dst: PathBuf = PathBuf::from(destination::destination(file, &func, extra, false, ext));
    let dst_tmp: PathBuf = PathBuf::from(destination::destination(file, &func, extra, true, ext));
    if dst.exists() {
        let mut existing = File::open(&dst)?;
        let mut existing_content = String::new();
        existing.read_to_string(&mut existing_content)?;
        if new_content != existing_content {
            let mut new = File::create(&dst_tmp)?;
            new.write_all(&new_content.into_bytes())?;
            let process = Command::new("git")
                .args(&[
                    "diff",
                    "--color",
                    "--no-index",
                    "--",
                    dst.to_str().ok_or(err_msg("PathNotUtf8"))?,
                    dst_tmp.to_str().ok_or(err_msg("PathNotUtf8"))?,
                ]).output()?;
            println!("{}", String::from_utf8(process.stdout)?);
            println!(
                "\n\nIf the new output is correct, run: \nmv {} {}\n\n",
                (env::current_dir()?.join(dst_tmp))
                    .to_str()
                    .ok_or(err_msg("PathNotUtf8"))?,
                (env::current_dir()?.join(dst.clone()))
                    .to_str()
                    .ok_or(err_msg("PathNotUtf8"))?
            );
            Err(err_msg("TestFailed"))?
        }
    } else {
        let parent = dst.parent().ok_or(err_msg("TestFailed"))?;
        Command::new("mkdir")
            .args(&["-p", parent.to_str().ok_or(err_msg("PathNotUtf8"))?])
            .output()?;
        let mut new = File::create(&dst_tmp)?;
        new.write_all(&new_content.into_bytes())?;
        let process = Command::new("git")
            .args(&[
                "diff",
                "--color",
                "--no-index",
                "--",
                "/dev/null",
                dst_tmp.to_str().ok_or(err_msg("PathNotUtf8"))?,
            ]).output()?;
        println!("{}", String::from_utf8(process.stdout)?);
        println!(
            "\n\nIf the new output is correct, run: \nmv {} {}\n\n",
            (env::current_dir()?.join(dst_tmp))
                .to_str()
                .ok_or(err_msg("PathNotUtf8"))?,
            (env::current_dir()?.join(dst.clone()))
                .to_str()
                .ok_or(err_msg("PathNotUtf8"))?
        );
        Err(err_msg("TestFailed"))?
    }

    Ok(())
}