62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
|
|
use pretty_assertions::assert_eq;
|
||
|
|
use tree_sitter::Parser;
|
||
|
|
|
||
|
|
use crate::{
|
||
|
|
generate::generate_parser_for_grammar,
|
||
|
|
tests::helpers::fixtures::{fixtures_dir, get_test_language},
|
||
|
|
};
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_grammar_that_should_hang_and_not_segfault() {
|
||
|
|
use std::sync::mpsc;
|
||
|
|
|
||
|
|
let (tx, rx) = mpsc::channel();
|
||
|
|
|
||
|
|
std::thread::spawn(move || {
|
||
|
|
let (parser_name, parser_code) = generate_parser_for_grammar(
|
||
|
|
r#"
|
||
|
|
{
|
||
|
|
"name": "get_col_should_hang_not_crash",
|
||
|
|
"rules": {
|
||
|
|
"source_file": {
|
||
|
|
"type": "SEQ",
|
||
|
|
"members": [ { "type": "SYMBOL", "name": "test" } ]
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"extras": [ { "type": "PATTERN", "value": "\\s" } ],
|
||
|
|
"externals": [ { "type": "SYMBOL", "name": "test" } ]
|
||
|
|
}
|
||
|
|
"#,
|
||
|
|
)
|
||
|
|
.unwrap();
|
||
|
|
|
||
|
|
let mut parser = Parser::new();
|
||
|
|
parser
|
||
|
|
.set_language(get_test_language(
|
||
|
|
&parser_name,
|
||
|
|
&parser_code,
|
||
|
|
Some(
|
||
|
|
fixtures_dir()
|
||
|
|
.join("test_grammars")
|
||
|
|
.join("get_col_should_hang_not_crash")
|
||
|
|
.as_path(),
|
||
|
|
),
|
||
|
|
))
|
||
|
|
.unwrap();
|
||
|
|
|
||
|
|
let code_that_should_hang = "\nHello";
|
||
|
|
|
||
|
|
parser.parse(code_that_should_hang, None).unwrap();
|
||
|
|
|
||
|
|
// Won't be reached
|
||
|
|
let _ = tx.send(());
|
||
|
|
});
|
||
|
|
|
||
|
|
// Ok signifies that it did not hang
|
||
|
|
// RecvTimeoutError::Disconnected signifies that the parser thread exited unexpectedly (crashed)
|
||
|
|
assert_eq!(
|
||
|
|
rx.recv_timeout(std::time::Duration::from_secs(5)),
|
||
|
|
Err(mpsc::RecvTimeoutError::Timeout)
|
||
|
|
);
|
||
|
|
}
|