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 atelier_core::io::lines::make_line_oriented_form;
use atelier_core::io::{read_model_from_file, read_model_from_string, ModelReader};
use atelier_core::model::Model;
use pretty_assertions::assert_eq;
use std::fs;
use std::path::{Path, PathBuf};

// ------------------------------------------------------------------------------------------------
// Public Types
// ------------------------------------------------------------------------------------------------

/// A Type that represents the result of the `LineOrientedWriter` output.
pub type ExpectedLines = Vec<&'static str>;

pub struct TestCaseModel {
    pub model: Model,
    pub expected_lines: ExpectedLines,
}

// ------------------------------------------------------------------------------------------------
// Private Types
// ------------------------------------------------------------------------------------------------

#[cfg(windows)]
const LINE_ENDING: &str = "\r\n";
#[cfg(not(windows))]
const LINE_ENDING: &str = "\n";

// ------------------------------------------------------------------------------------------------
// Public Functions
// ------------------------------------------------------------------------------------------------

pub fn parse_and_compare_model(input_str: &str, reader: &mut impl ModelReader, expected: Model) {
    println!("input to parse:\n{}", input_str);
    horizontal_line();
    match read_model_from_string(reader, input_str) {
        Ok(actual) => {
            println!("actual:\n{:#?}", actual);
            horizontal_line();
            assert_eq!(actual, expected);
        }
        Err(err) => panic!("error: {:#?}", err),
    }
}

pub fn parse_and_compare_to_files(
    reader: &mut impl ModelReader,
    actual_path: &Path,
    expected_path: &Path,
) {
    let result = read_model_from_file(reader, PathBuf::from(actual_path));
    match result {
        Ok(model) => {
            compare_model_to_file(model, expected_path);
        }
        Err(err) => panic!("{}", err),
    }
}

pub fn parse_and_compare_to_file(input_str: &str, reader: &mut impl ModelReader, file_path: &Path) {
    println!("input to parse:\n{}", input_str);
    horizontal_line();
    match read_model_from_string(reader, input_str) {
        Ok(actual) => {
            println!("actual:\n{:#?}", actual);
            horizontal_line();
            compare_model_to_file(actual, file_path);
        }
        Err(err) => panic!("error: {:#?}", err),
    }
}

pub fn compare_model_to_file(model: Model, file_path: &Path) {
    let expected_lines: Vec<String> = fs::read_to_string(file_path)
        .unwrap()
        .split(LINE_ENDING)
        .map(str::to_string)
        .collect();

    let actual_lines: Vec<String> = make_line_oriented_form(&model)
        .iter()
        .map(|s| {
            if cfg!(windows) {
                if s.contains("\r\n") {
                    println!("*** FIXING WINDOWS LINE ENDINGS");
                }
                s.replace("\r\n", "😀")
            } else {
                s.to_string()
            }
        })
        .collect();

    assert_eq!(actual_lines, expected_lines);
}

// ------------------------------------------------------------------------------------------------
// Implementations
// ------------------------------------------------------------------------------------------------

// ------------------------------------------------------------------------------------------------
// Private Functions
// ------------------------------------------------------------------------------------------------

#[inline]
fn horizontal_line() {
    println!("------------------------------------------------------------------------------------------------");
}
// ------------------------------------------------------------------------------------------------
// Modules
// ------------------------------------------------------------------------------------------------

pub mod parts;

pub mod examples;