use crate::tree::emit::{EmitOptions, syntax_root_to_string};
use crate::tree::red::SyntaxNode;
pub use crate::tree::sexp::{SexpOptions, syntax_node_to_sexp};
#[inline]
#[must_use]
pub fn trees_equal(a: &SyntaxNode, b: &SyntaxNode) -> bool {
syntax_root_to_string(a, &EmitOptions::full()) == syntax_root_to_string(b, &EmitOptions::full())
}
#[inline]
#[must_use]
pub fn trees_equal_semantic(a: &SyntaxNode, b: &SyntaxNode) -> bool {
syntax_root_to_string(a, &EmitOptions::semantic_only())
== syntax_root_to_string(b, &EmitOptions::semantic_only())
}
#[must_use]
pub fn format_diff(expected: &SyntaxNode, got: &SyntaxNode) -> String {
let expected_str = syntax_root_to_string(expected, &EmitOptions::full());
let got_str = syntax_root_to_string(got, &EmitOptions::full());
if expected_str == got_str {
return "trees are equal".to_string();
}
format!(
"expected ({} bytes):\n {:?}\ngot ({} bytes):\n {:?}",
expected_str.len(),
truncate_for_display(&expected_str, 200),
got_str.len(),
truncate_for_display(&got_str, 200)
)
}
fn truncate_for_display(s: &str, max: usize) -> String {
let s = s.replace('\n', "\\n");
if s.len() <= max {
s
} else {
format!("{}...", &s[..max])
}
}
pub fn assert_parse_eq<E: std::fmt::Debug>(
parse_result: Result<Option<SyntaxNode>, E>,
_input: &str,
expected_sexp: &str,
options: &SexpOptions,
) {
let root = parse_result
.unwrap_or_else(|e| panic!("parse failed: {e:?}"))
.expect("parse returned None (no root)");
let got = syntax_node_to_sexp(&root, options);
assert_eq!(
got, expected_sexp,
"S-expression mismatch:\nexpected:\n {expected_sexp}\ngot:\n {got}"
);
}
#[macro_export]
macro_rules! assert_parse {
($parse_fn:expr, $input:expr, $expected_sexp:expr) => {
$crate::extras::diff::assert_parse_eq(
$parse_fn($input),
$input,
$expected_sexp,
&$crate::tree::sexp::SexpOptions::semantic_only(),
)
};
($parse_fn:expr, $input:expr, $expected_sexp:expr, $options:expr) => {
$crate::extras::diff::assert_parse_eq($parse_fn($input), $input, $expected_sexp, $options)
};
}