use std::{
env, fs,
path::{Path, PathBuf},
};
use expect_test::expect_file;
use crate::{ApolloCompiler, ApolloDiagnostic, AstDatabase};
#[test]
fn compiler_tests() {
dir_tests(&test_data_dir(), &["ok"], "txt", |text, path| {
let mut compiler = ApolloCompiler::new();
let file_id = compiler.add_document(text, path);
let errors = compiler.validate();
let ast = compiler.db.ast(file_id);
assert_diagnostics_are_absent(&errors, path);
format!("{:?}", ast)
});
dir_tests(&test_data_dir(), &["diagnostics"], "txt", |text, path| {
let mut compiler = ApolloCompiler::new();
compiler.add_document(text, path);
let diagnostics = compiler.validate();
assert_diagnostics_are_present(&diagnostics, path);
format!("{:#?}", diagnostics)
});
}
fn assert_diagnostics_are_present(errors: &[ApolloDiagnostic], path: &Path) {
assert!(
!errors.is_empty(),
"There should be diagnostics in the file {:?}",
path.display()
);
}
fn assert_diagnostics_are_absent(errors: &[ApolloDiagnostic], path: &Path) {
if !errors.is_empty() {
let formatted: Vec<String> = errors.iter().map(|e| format!("{:?}", e)).collect();
println!("{:?}", formatted.join("\n"));
panic!(
"There should be no diagnostics in the file {:?}",
path.display(),
);
}
}
fn dir_tests<F>(test_data_dir: &Path, paths: &[&str], outfile_extension: &str, f: F)
where
F: Fn(&str, &Path) -> String,
{
for (path, input_code) in collect_graphql_files(test_data_dir, paths) {
let mut actual = f(&input_code, &path);
actual.push('\n');
let path = path.with_extension(outfile_extension);
expect_file![path].assert_eq(&actual)
}
}
fn collect_graphql_files(root_dir: &Path, paths: &[&str]) -> Vec<(PathBuf, String)> {
paths
.iter()
.flat_map(|path| {
let path = root_dir.to_owned().join(path);
graphql_files_in_dir(&path).into_iter()
})
.map(|path| {
let text = fs::read_to_string(&path)
.unwrap_or_else(|_| panic!("File at {:?} should be valid", path));
(path, text)
})
.collect()
}
fn graphql_files_in_dir(dir: &Path) -> Vec<PathBuf> {
let mut acc = Vec::new();
for file in fs::read_dir(dir).unwrap() {
let file = file.unwrap();
let path = file.path();
if path.extension().unwrap_or_default() == "graphql" {
acc.push(path);
}
}
acc.sort();
acc
}
fn test_data_dir() -> PathBuf {
project_root().join("apollo-compiler/test_data")
}
fn project_root() -> PathBuf {
Path::new(
&env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
)
.ancestors()
.nth(1)
.unwrap()
.to_path_buf()
}