use regex::Regex;
use serde_generate::{test_utils, typescript, CodeGeneratorConfig, Encoding, SourceInstaller};
use std::{collections::BTreeMap, fs::File, path::Path, process::Command};
use tempfile::tempdir;
fn test_typescript_code_compiles_with_config(
dir_path: &Path,
config: &CodeGeneratorConfig,
) -> std::path::PathBuf {
let registry = test_utils::get_registry().unwrap();
make_output_file(dir_path);
let installer = typescript::Installer::new(dir_path.to_path_buf());
installer.install_serde_runtime().unwrap();
assert_deno_info(dir_path.join("bcs/mod.ts").as_path());
installer.install_bcs_runtime().unwrap();
assert_deno_info(dir_path.join("serde/mod.ts").as_path());
let source_path = dir_path.join("testing").join("test.ts");
let mut source = File::create(&source_path).unwrap();
let generator = typescript::CodeGenerator::new(config);
generator.output(&mut source, ®istry).unwrap();
assert_deno_info(&source_path);
dir_path.join("testing")
}
fn assert_deno_info(ts_path: &Path) {
let output = Command::new("deno")
.arg("info")
.arg(ts_path)
.output()
.expect("deno info failed, is deno installed? brew install deno");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(
!is_error_output(stdout.as_str()),
"deno info detected an error\n{}",
stdout
);
}
fn is_error_output(output: &str) -> bool {
let re = Regex::new(r"\berror\b").unwrap();
re.is_match(output)
}
fn make_output_file(dir: &Path) {
std::fs::create_dir_all(dir.join("testing")).unwrap_or(());
}
#[test]
fn test_is_error_output() {
let table = vec![
("file:///var/folders/l0/x592_pjj18n6r2m0nqn05vmc0000gn/T/.tmp5NPlE2/serde/mod.ts (176B)", false),
("https://deno.land/std@0.85.0/node/_errors.ts (60.89KB)", false),
("error: Cannot resolve module \"file:///var/folders/l0/x592_pjj18n6r2m0nqn05vmc0000gn/T/.tmp5NPlE2/bcs/mod.ts\"", true),
("file:///var/folders/l0/x592_pjj18n6r2m0nqn05vmc0000gn/T/.tmpG1an6c/something/noSerializer.ts (error)", true),
];
for (input, expectation) in table {
assert_eq!(is_error_output(input), expectation);
}
}
#[test]
fn test_typescript_code_compiles_with_bcs() {
let dir = tempdir().unwrap();
let config =
CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![Encoding::Bcs]);
test_typescript_code_compiles_with_config(dir.path(), &config);
}
#[test]
fn test_typescript_code_compiles_with_comments() {
let dir = tempdir().unwrap();
let comments = vec![(vec!["SerdeData".to_string()], "Some\ncomments".to_string())]
.into_iter()
.collect();
let config = CodeGeneratorConfig::new("testing".to_string()).with_comments(comments);
let path = test_typescript_code_compiles_with_config(dir.path(), &config);
let content = std::fs::read_to_string(path.join("test.ts")).unwrap();
assert!(content.contains(
r#"
/**
* Some
* comments
*/
"#
));
}
#[test]
fn test_typescript_code_compiles_with_external_definitions() {
let dir = tempdir().unwrap();
std::fs::create_dir_all(dir.path().join("external")).unwrap_or(());
std::fs::write(
dir.path().join("external/mod.ts"),
"export const CustomType = 5;",
)
.unwrap();
let mut external_definitions = BTreeMap::new();
external_definitions.insert(String::from("external"), vec![String::from("CustomType")]);
let config = CodeGeneratorConfig::new("testing".to_string())
.with_external_definitions(external_definitions);
test_typescript_code_compiles_with_config(dir.path(), &config);
}