These are much harder to solve, and that's exactly what I'm going to do now. Basically, it's finally time to refactor `kyomato` into several crates.
145 lines
5.2 KiB
Rust
145 lines
5.2 KiB
Rust
use std::{ffi::OsString, path::PathBuf, str::FromStr};
|
|
|
|
const CLEAR: &str = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" ;
|
|
const INPUT_DIR: &str = "./tests/input_files";
|
|
const LEX_DIR: &str = "./tests/lex_files";
|
|
|
|
fn input_files() -> impl Iterator<Item = (OsString, String)> {
|
|
std::fs::read_dir(INPUT_DIR)
|
|
.expect("Should be able to access input directory")
|
|
.map(|file| {
|
|
let file_path = file
|
|
.expect("Should be able to access files in input directory")
|
|
.path();
|
|
let input =
|
|
std::fs::read_to_string(&file_path).expect("Should be able to read input files");
|
|
(OsString::from(file_path.file_name().unwrap()), input)
|
|
})
|
|
}
|
|
|
|
/// Prints input file's lex into the stdout, for inspection
|
|
#[ignore = "manual"]
|
|
#[test]
|
|
fn show_lex() {
|
|
for (_, input) in input_files() {
|
|
let parsed = match kyomato_lib::lex(input.as_str()) {
|
|
Ok(ok) => ok,
|
|
Err(err) => {
|
|
panic!("Should successfully parse the input: {err:#?}");
|
|
}
|
|
};
|
|
println!("{parsed:#?}");
|
|
std::io::stdin()
|
|
.read_line(&mut String::new())
|
|
.expect("Should be able to read a line");
|
|
println!("{}", CLEAR);
|
|
}
|
|
}
|
|
|
|
// TODO rewrite to use serde-json after token rework
|
|
/// Generates representation of a parsed tokens, for automated testing to compare with
|
|
#[cfg(feature = "serde")]
|
|
#[ignore = "manual"]
|
|
#[test]
|
|
fn gen_lex_output() {
|
|
use std::{fs::File, io::Write, os::unix::fs::FileExt, path::PathBuf, str::FromStr};
|
|
{
|
|
use std::io::Read;
|
|
print!("Are you sure? This will rewrite previous test outputs: [y/N]: ");
|
|
std::io::stdout()
|
|
.flush()
|
|
.expect("Should be able to flush the stdout");
|
|
|
|
let mut buf = [0u8; 1];
|
|
std::io::stdin()
|
|
.read_exact(&mut buf)
|
|
.expect("Should be able to read stdin");
|
|
if buf[0] != b'y' {
|
|
println!("\nAborting...");
|
|
return;
|
|
}
|
|
}
|
|
let mut output_path = PathBuf::from_str(LEX_DIR).unwrap();
|
|
if !output_path.is_dir() {
|
|
std::fs::create_dir(&output_path).expect("Failed to create directory");
|
|
}
|
|
for (filename, input) in input_files() {
|
|
let (title_info, tokens) = match kyomato_lib::lex(input.as_str()) {
|
|
Ok(ok) => ok,
|
|
Err(err) => {
|
|
panic!("Input files should be successfully parsed: {err:#?}");
|
|
}
|
|
};
|
|
// create representation of the parsed tokens
|
|
// TODO this part should be replaced, once serde is supported
|
|
let repr = format!("{:#?}\n{:#?}", title_info, tokens);
|
|
// write the result to output directory
|
|
let output_file = {
|
|
output_path.push(filename);
|
|
output_path.set_extension("txt");
|
|
let output_file = if output_path.is_file() {
|
|
File::options()
|
|
.write(true)
|
|
.truncate(true)
|
|
.open(&output_path)
|
|
} else {
|
|
File::create(&output_path)
|
|
}
|
|
.expect("Failed to create output file");
|
|
output_path.pop();
|
|
output_file
|
|
};
|
|
output_file
|
|
.write_at(repr.as_bytes(), 0)
|
|
.expect("Failed to write into output file");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_lex() {
|
|
let mut output_results = Vec::new();
|
|
let mut output_path = PathBuf::from_str(LEX_DIR).unwrap();
|
|
if !output_path.is_dir() {
|
|
std::fs::create_dir(&output_path).expect("Failed to create directory");
|
|
}
|
|
for (filename, input) in input_files() {
|
|
let (title_info, tokens) = match kyomato_lib::lex(input.as_str()) {
|
|
Ok(ok) => ok,
|
|
Err(err) => {
|
|
panic!("Should successfully parse the input: {err:#?}");
|
|
}
|
|
};
|
|
// create representation of the parsed tokens
|
|
// TODO this part should be replaced, once serde is supported
|
|
let repr = format!("{:#?}\n{:#?}", title_info, tokens);
|
|
// write the result to output directory
|
|
let expected_output = {
|
|
output_path.push(&filename);
|
|
output_path.set_extension("txt");
|
|
let output =
|
|
std::fs::read_to_string(&output_path).expect("Failed to read expected output");
|
|
output_path.pop();
|
|
output
|
|
};
|
|
output_results.push((filename, repr, expected_output));
|
|
}
|
|
let total = output_results.len();
|
|
let success = output_results
|
|
.iter()
|
|
.filter(|(_, real, expected)| real == expected)
|
|
.count();
|
|
let failed = total - success;
|
|
if failed > 0 {
|
|
let mut output_msg = String::new();
|
|
output_msg.push_str(&format!("passed: ({success}/{total})\nFailures:\n"));
|
|
for (filename, real, expected) in output_results {
|
|
if real != expected {
|
|
output_msg.push_str(&format!(
|
|
"\tFilename: {}\n\tActual: {real}\n\tExpected: {expected}\n\n",
|
|
filename.to_string_lossy(),
|
|
));
|
|
}
|
|
}
|
|
panic!("{output_msg}");
|
|
}
|
|
}
|