use indoc::indoc;
use tree_sitter::Parser;
use tree_sitter_graph::ast::File;
use tree_sitter_graph::functions::Functions;
use tree_sitter_graph::ExecutionConfig;
use tree_sitter_graph::ExecutionError;
use tree_sitter_graph::Identifier;
use tree_sitter_graph::NoCancellation;
use tree_sitter_graph::Variables;
fn init_log() {
let _ = env_logger::builder()
.is_test(true)
.format_level(false)
.format_target(false)
.format_timestamp(None)
.try_init(); }
fn execute(python_source: &str, dsl_source: &str) -> Result<String, ExecutionError> {
init_log();
let mut parser = Parser::new();
parser
.set_language(&tree_sitter_python::LANGUAGE.into())
.unwrap();
let tree = parser.parse(python_source, None).unwrap();
let file =
File::from_str(tree_sitter_python::LANGUAGE.into(), dsl_source).expect("Cannot parse file");
let functions = Functions::stdlib();
let mut globals = Variables::new();
globals
.add(Identifier::from("filename"), "test.py".into())
.map_err(|_| ExecutionError::DuplicateVariable("filename".into()))?;
let mut config = ExecutionConfig::new(&functions, &globals);
let graph = file.execute(&tree, python_source, &mut config, &NoCancellation)?;
let result = graph.pretty_print().to_string();
Ok(result)
}
fn check_execution(python_source: &str, dsl_source: &str, expected_graph: &str) {
match execute(python_source, dsl_source) {
Ok(actual_graph) => assert_eq!(actual_graph, expected_graph),
Err(e) => panic!("Could not execute file: {}", e),
}
}
fn fail_execution(python_source: &str, dsl_source: &str) {
if let Ok(_) = execute(python_source, dsl_source) {
panic!("Execution succeeded unexpectedly");
}
}
#[test]
fn can_eq_equal_bools() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) eq = (eq #true #true)
}
"#},
indoc! {r#"
node 0
eq: #true
"#},
);
}
#[test]
fn can_eq_nonequal_bools() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) eq = (eq #true #false)
}
"#},
indoc! {r#"
node 0
eq: #false
"#},
);
}
#[test]
fn cannot_eq_bool_and_string() {
fail_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) eq = (eq #true "false")
}
"#},
);
}
#[test]
fn can_format_string_null_and_escaped_braces() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (format "{} : {{ {} }}" "foo" #null)
}
"#},
indoc! {r#"
node 0
str: "foo : { #null }"
"#},
);
}
#[test]
fn cannot_format_with_missing_parameter() {
fail_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (format "{} : {{ {} }}" "foo")
}
"#},
);
}
#[test]
fn cannot_format_with_extra_parameter() {
fail_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (format "{} : {{ {} }}" "foo" #null 42)
}
"#},
);
}
#[test]
fn cannot_format_with_unexpected_opening_brace() {
fail_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (format "{} : { {} }}" "foo" #null)
}
"#},
);
}
#[test]
fn cannot_format_with_unexpected_closing_brace() {
fail_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (format "{} : {{ {} }" "foo" #null)
}
"#},
);
}
#[test]
fn can_concat_lists() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) xs = (concat [1, 2] [] [3, 4, 5])
}
"#},
indoc! {r#"
node 0
xs: [1, 2, 3, 4, 5]
"#},
);
}
#[test]
fn can_join_list_with_separator() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (join [1, 2, 3] ".")
}
"#},
indoc! {r#"
node 0
str: "1.2.3"
"#},
);
}
#[test]
fn can_join_list_without_separator() {
check_execution(
"pass",
indoc! {r#"
(module)
{
node n
attr (n) str = (join [1, 2, 3])
}
"#},
indoc! {r#"
node 0
str: "123"
"#},
);
}