fork of https://github.com/tree-sitter/tree-sitter-graph
1// -*- coding: utf-8 -*-
2// ------------------------------------------------------------------------------------------------
3// Copyright © 2021, tree-sitter authors.
4// Licensed under either of Apache License, Version 2.0, or MIT license, at your option.
5// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
6// ------------------------------------------------------------------------------------------------
7
8use indoc::indoc;
9use tree_sitter::Parser;
10use tree_sitter_graph::ast::File;
11use tree_sitter_graph::functions::Functions;
12use tree_sitter_graph::ExecutionConfig;
13use tree_sitter_graph::ExecutionError;
14use tree_sitter_graph::Identifier;
15use tree_sitter_graph::NoCancellation;
16use tree_sitter_graph::Variables;
17
18fn init_log() {
19 let _ = env_logger::builder()
20 .is_test(true)
21 .format_level(false)
22 .format_target(false)
23 .format_timestamp(None)
24 .try_init(); // try, because earlier test may have already initialized it
25}
26
27fn execute(python_source: &str, dsl_source: &str) -> Result<String, ExecutionError> {
28 init_log();
29 let mut parser = Parser::new();
30 parser
31 .set_language(&tree_sitter_python::LANGUAGE.into())
32 .unwrap();
33 let tree = parser.parse(python_source, None).unwrap();
34 let file =
35 File::from_str(tree_sitter_python::LANGUAGE.into(), dsl_source).expect("Cannot parse file");
36 let functions = Functions::stdlib();
37 let mut globals = Variables::new();
38 globals
39 .add(Identifier::from("filename"), "test.py".into())
40 .map_err(|_| ExecutionError::DuplicateVariable("filename".into()))?;
41 let mut config = ExecutionConfig::new(&functions, &globals);
42 let graph = file.execute(&tree, python_source, &mut config, &NoCancellation)?;
43 let result = graph.pretty_print().to_string();
44 Ok(result)
45}
46
47fn check_execution(python_source: &str, dsl_source: &str, expected_graph: &str) {
48 match execute(python_source, dsl_source) {
49 Ok(actual_graph) => assert_eq!(actual_graph, expected_graph),
50 Err(e) => panic!("Could not execute file: {}", e),
51 }
52}
53
54fn fail_execution(python_source: &str, dsl_source: &str) {
55 if let Ok(_) = execute(python_source, dsl_source) {
56 panic!("Execution succeeded unexpectedly");
57 }
58}
59
60#[test]
61fn can_eq_equal_bools() {
62 check_execution(
63 "pass",
64 indoc! {r#"
65 (module)
66 {
67 node n
68 attr (n) eq = (eq #true #true)
69 }
70 "#},
71 indoc! {r#"
72 node 0
73 eq: #true
74 "#},
75 );
76}
77
78#[test]
79fn can_eq_nonequal_bools() {
80 check_execution(
81 "pass",
82 indoc! {r#"
83 (module)
84 {
85 node n
86 attr (n) eq = (eq #true #false)
87 }
88 "#},
89 indoc! {r#"
90 node 0
91 eq: #false
92 "#},
93 );
94}
95
96#[test]
97fn cannot_eq_bool_and_string() {
98 fail_execution(
99 "pass",
100 indoc! {r#"
101 (module)
102 {
103 node n
104 attr (n) eq = (eq #true "false")
105 }
106 "#},
107 );
108}
109
110#[test]
111fn can_format_string_null_and_escaped_braces() {
112 check_execution(
113 "pass",
114 indoc! {r#"
115 (module)
116 {
117 node n
118 attr (n) str = (format "{} : {{ {} }}" "foo" #null)
119 }
120 "#},
121 indoc! {r#"
122 node 0
123 str: "foo : { #null }"
124 "#},
125 );
126}
127
128#[test]
129fn cannot_format_with_missing_parameter() {
130 fail_execution(
131 "pass",
132 indoc! {r#"
133 (module)
134 {
135 node n
136 attr (n) str = (format "{} : {{ {} }}" "foo")
137 }
138 "#},
139 );
140}
141
142#[test]
143fn cannot_format_with_extra_parameter() {
144 fail_execution(
145 "pass",
146 indoc! {r#"
147 (module)
148 {
149 node n
150 attr (n) str = (format "{} : {{ {} }}" "foo" #null 42)
151 }
152 "#},
153 );
154}
155
156#[test]
157fn cannot_format_with_unexpected_opening_brace() {
158 fail_execution(
159 "pass",
160 indoc! {r#"
161 (module)
162 {
163 node n
164 attr (n) str = (format "{} : { {} }}" "foo" #null)
165 }
166 "#},
167 );
168}
169
170#[test]
171fn cannot_format_with_unexpected_closing_brace() {
172 fail_execution(
173 "pass",
174 indoc! {r#"
175 (module)
176 {
177 node n
178 attr (n) str = (format "{} : {{ {} }" "foo" #null)
179 }
180 "#},
181 );
182}
183
184#[test]
185fn can_concat_lists() {
186 check_execution(
187 "pass",
188 indoc! {r#"
189 (module)
190 {
191 node n
192 attr (n) xs = (concat [1, 2] [] [3, 4, 5])
193 }
194 "#},
195 indoc! {r#"
196 node 0
197 xs: [1, 2, 3, 4, 5]
198 "#},
199 );
200}
201
202#[test]
203fn can_join_list_with_separator() {
204 check_execution(
205 "pass",
206 indoc! {r#"
207 (module)
208 {
209 node n
210 attr (n) str = (join [1, 2, 3] ".")
211 }
212 "#},
213 indoc! {r#"
214 node 0
215 str: "1.2.3"
216 "#},
217 );
218}
219
220#[test]
221fn can_join_list_without_separator() {
222 check_execution(
223 "pass",
224 indoc! {r#"
225 (module)
226 {
227 node n
228 attr (n) str = (join [1, 2, 3])
229 }
230 "#},
231 indoc! {r#"
232 node 0
233 str: "123"
234 "#},
235 );
236}