use crate::test_utils;
use serde_generate::{python3, CodeGeneratorConfig, Encoding, SourceInstaller};
use std::{collections::BTreeMap, fs::File, process::Command};
use tempfile::{tempdir, TempDir};
fn test_that_python_code_parses_with_config(
config: &CodeGeneratorConfig,
) -> (TempDir, std::path::PathBuf) {
let registry = test_utils::get_registry().unwrap();
let dir = tempdir().unwrap();
let source_path = dir.path().join("test.py");
let mut source = File::create(&source_path).unwrap();
let generator = python3::CodeGenerator::new(config);
generator.output(&mut source, ®istry).unwrap();
let python_path = format!(
"{}:runtime/python",
std::env::var("PYTHONPATH").unwrap_or_default()
);
let status = Command::new("python3")
.arg(&source_path)
.env("PYTHONPATH", python_path)
.status()
.unwrap();
assert!(status.success());
(dir, source_path)
}
#[test]
fn test_that_python_code_parses() {
let config = CodeGeneratorConfig::new("testing".to_string());
test_that_python_code_parses_with_config(&config);
}
#[test]
fn test_that_python_code_parses_without_serialization() {
let config = CodeGeneratorConfig::new("testing".to_string()).with_serialization(false);
test_that_python_code_parses_with_config(&config);
}
#[test]
fn test_that_python_code_parses_with_bcs() {
let config =
CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![Encoding::Bcs]);
test_that_python_code_parses_with_config(&config);
}
#[test]
fn test_that_python_code_parses_with_bincode() {
let config =
CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![Encoding::Bincode]);
test_that_python_code_parses_with_config(&config);
}
#[test]
fn test_that_python_code_parses_with_comments() {
let comments = vec![
(
vec!["testing".to_string(), "SerdeData".to_string()],
"Some\ncomments".to_string(),
),
(
vec![
"testing".to_string(),
"List".to_string(),
"Node".to_string(),
],
"Some other comments".to_string(),
),
]
.into_iter()
.collect();
let config = CodeGeneratorConfig::new("testing".to_string()).with_comments(comments);
let (_dir, source_path) = test_that_python_code_parses_with_config(&config);
let content = std::fs::read_to_string(source_path).unwrap();
assert!(content.contains(
r#"
"""Some
comments
"""
"#
));
assert!(content.contains(
r#"
"""Some other comments
"""
"#
));
}
#[test]
fn test_python_code_with_external_definitions() {
let registry = test_utils::get_registry().unwrap();
let dir = tempdir().unwrap();
let source_path = dir.path().join("test.py");
let mut source = File::create(&source_path).unwrap();
let mut definitions = BTreeMap::new();
definitions.insert("pkg.foo".to_string(), vec!["Tree".to_string()]);
let config =
CodeGeneratorConfig::new("testing".to_string()).with_external_definitions(definitions);
let generator = python3::CodeGenerator::new(&config);
generator.output(&mut source, ®istry).unwrap();
let content = std::fs::read_to_string(&source_path).unwrap();
assert!(content.contains("from pkg import foo"));
assert!(content.contains("value: foo.Tree"));
assert!(!content.contains("value: Tree"));
}
#[test]
fn test_that_python_code_parses_with_custom_code() {
let custom_code = vec![
(
vec!["testing".to_string(), "SerdeData".to_string()],
"def nothing1(self):\n pass".to_string(),
),
(
vec![
"testing".to_string(),
"List".to_string(),
"Node".to_string(),
],
"def nothing2(self):\n pass".to_string(),
),
]
.into_iter()
.collect();
let config = CodeGeneratorConfig::new("testing".to_string()).with_custom_code(custom_code);
let (_dir, source_path) = test_that_python_code_parses_with_config(&config);
let content = std::fs::read_to_string(source_path).unwrap();
assert!(content.contains("nothing1"));
assert!(content.contains("nothing2"));
}
#[test]
fn test_that_installed_python_code_passes_pyre_check() {
let registry = test_utils::get_registry().unwrap();
let dir = tempdir().unwrap();
let config =
CodeGeneratorConfig::new("testing".to_string()).with_encodings(vec![Encoding::Bcs]);
let installer = python3::Installer::new(dir.path().join("src"), None);
installer.install_module(&config, ®istry).unwrap();
installer.install_serde_runtime().unwrap();
installer.install_bincode_runtime().unwrap();
installer.install_bcs_runtime().unwrap();
let status = Command::new("cp")
.arg("-r")
.arg("runtime/python/bcs/test_bcs.py")
.arg(dir.path().join("src/bcs"))
.status()
.unwrap();
assert!(status.success());
let status = Command::new("cp")
.arg("-r")
.arg("runtime/python/bincode/test_bincode.py")
.arg(dir.path().join("src/bincode"))
.status()
.unwrap();
assert!(status.success());
let site_packages = Command::new("python3")
.arg("-c")
.arg("import os; import numpy; print(os.path.dirname(numpy.__path__[0]), end='')")
.output()
.unwrap()
.stdout;
let local_bin_path = which::which("pyre")
.unwrap()
.parent()
.unwrap()
.to_path_buf();
let status = Command::new("pyre")
.current_dir(dir.path())
.arg("--source-directory")
.arg("src")
.arg("--noninteractive")
.arg("--binary")
.arg(local_bin_path.join("pyre.bin"))
.arg("--typeshed")
.arg(local_bin_path.join("../lib/pyre_check/typeshed"))
.arg("--search-path")
.arg(String::from_utf8_lossy(&site_packages).as_ref())
.arg("check")
.status()
.unwrap();
assert!(status.success());
}
#[test]
fn test_python_autotest() {
let status = Command::new("python3")
.arg("-m")
.arg("unittest")
.arg("discover")
.arg("-s")
.arg("runtime/python")
.status()
.unwrap();
assert!(status.success());
}