cli: Check queries when running tree-sitter test
This commit is contained in:
parent
b73b31356d
commit
e14e285a10
6 changed files with 69 additions and 20 deletions
|
|
@ -52,7 +52,25 @@ impl Error {
|
|||
|
||||
impl<'a> From<QueryError> for Error {
|
||||
fn from(error: QueryError) -> Self {
|
||||
Error::new(format!("{:?}", error))
|
||||
match error {
|
||||
QueryError::Capture(row, c) => Error::new(format!(
|
||||
"Query error on line {}: Invalid capture name {}",
|
||||
row, c
|
||||
)),
|
||||
QueryError::Field(row, f) => Error::new(format!(
|
||||
"Query error on line {}: Invalid field name {}",
|
||||
row, f
|
||||
)),
|
||||
QueryError::NodeType(row, t) => Error::new(format!(
|
||||
"Query error on line {}. Invalid node type {}",
|
||||
row, t
|
||||
)),
|
||||
QueryError::Syntax(row, l) => Error::new(format!(
|
||||
"Query error on line {}. Invalid syntax:\n{}",
|
||||
row, l
|
||||
)),
|
||||
QueryError::Predicate(p) => Error::new(format!("Query error: {}", p)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -162,9 +162,15 @@ fn run() -> error::Result<()> {
|
|||
let debug = matches.is_present("debug");
|
||||
let debug_graph = matches.is_present("debug-graph");
|
||||
let filter = matches.value_of("filter");
|
||||
let corpus_path = current_dir.join("corpus");
|
||||
if let Some(language) = loader.languages_at_path(¤t_dir)?.first() {
|
||||
test::run_tests_at_path(*language, &corpus_path, debug, debug_graph, filter)?;
|
||||
test::run_tests_at_path(
|
||||
*language,
|
||||
¤t_dir.join("corpus"),
|
||||
debug,
|
||||
debug_graph,
|
||||
filter,
|
||||
)?;
|
||||
test::check_queries_at_path(*language, ¤t_dir.join("queries"))?;
|
||||
} else {
|
||||
eprintln!("No language found");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use std::fs;
|
|||
use std::io::{self, Write};
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
use tree_sitter::{Language, LogType, Parser};
|
||||
use tree_sitter::{Language, LogType, Parser, Query};
|
||||
|
||||
lazy_static! {
|
||||
static ref HEADER_REGEX: ByteRegex = ByteRegexBuilder::new(r"^===+\r?\n([^=]*)\r?\n===+\r?\n")
|
||||
|
|
@ -98,6 +98,22 @@ pub fn run_tests_at_path(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_queries_at_path(language: Language, path: &Path) -> Result<()> {
|
||||
for entry in fs::read_dir(path)? {
|
||||
let entry = entry?;
|
||||
let hidden = entry.file_name().to_str().unwrap_or("").starts_with(".");
|
||||
if !hidden {
|
||||
let content = fs::read_to_string(entry.path()).map_err(Error::wrap(|| {
|
||||
format!("Error reading query file {:?}", entry.file_name())
|
||||
}))?;
|
||||
Query::new(language, &content).map_err(Error::wrap(|| {
|
||||
format!("Error in query file {:?}", entry.file_name())
|
||||
}))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_diff_key() {
|
||||
println!(
|
||||
"\n{} / {}",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, "(if_statement"),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
"(if_statement", //
|
||||
" ^",
|
||||
|
|
@ -27,6 +28,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, "; comment 1\n; comment 2\n (if_statement))"),
|
||||
Err(QueryError::Syntax(
|
||||
3,
|
||||
[
|
||||
" (if_statement))", //
|
||||
" ^",
|
||||
|
|
@ -40,6 +42,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, "(if_statement identifier)"),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
"(if_statement identifier)", //
|
||||
" ^",
|
||||
|
|
@ -50,6 +53,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, "(if_statement condition:)"),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
"(if_statement condition:)", //
|
||||
" ^",
|
||||
|
|
@ -62,6 +66,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, r#"(identifier) "h "#),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
r#"(identifier) "h "#, //
|
||||
r#" ^"#,
|
||||
|
|
@ -73,6 +78,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, r#"((identifier) ()"#),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
"((identifier) ()", //
|
||||
" ^",
|
||||
|
|
@ -83,6 +89,7 @@ fn test_query_errors_on_invalid_syntax() {
|
|||
assert_eq!(
|
||||
Query::new(language, r#"((identifier) @x (eq? @x a"#),
|
||||
Err(QueryError::Syntax(
|
||||
1,
|
||||
[
|
||||
r#"((identifier) @x (eq? @x a"#,
|
||||
r#" ^"#,
|
||||
|
|
@ -100,23 +107,23 @@ fn test_query_errors_on_invalid_symbols() {
|
|||
|
||||
assert_eq!(
|
||||
Query::new(language, "(clas)"),
|
||||
Err(QueryError::NodeType("clas".to_string()))
|
||||
Err(QueryError::NodeType(1, "clas".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
Query::new(language, "(if_statement (arrayyyyy))"),
|
||||
Err(QueryError::NodeType("arrayyyyy".to_string()))
|
||||
Err(QueryError::NodeType(1, "arrayyyyy".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
Query::new(language, "(if_statement condition: (non_existent3))"),
|
||||
Err(QueryError::NodeType("non_existent3".to_string()))
|
||||
Err(QueryError::NodeType(1, "non_existent3".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
Query::new(language, "(if_statement condit: (identifier))"),
|
||||
Err(QueryError::Field("condit".to_string()))
|
||||
Err(QueryError::Field(1, "condit".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
Query::new(language, "(if_statement conditioning: (identifier))"),
|
||||
Err(QueryError::Field("conditioning".to_string()))
|
||||
Err(QueryError::Field(1, "conditioning".to_string()))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -140,7 +147,7 @@ fn test_query_errors_on_invalid_conditions() {
|
|||
);
|
||||
assert_eq!(
|
||||
Query::new(language, "((identifier) @id (eq? @id @ok))"),
|
||||
Err(QueryError::Capture("ok".to_string()))
|
||||
Err(QueryError::Capture(1, "ok".to_string()))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,10 +118,10 @@ pub struct QueryCapture<'a> {
|
|||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum QueryError {
|
||||
Syntax(String),
|
||||
NodeType(String),
|
||||
Field(String),
|
||||
Capture(String),
|
||||
Syntax(usize, String),
|
||||
NodeType(usize, String),
|
||||
Field(usize, String),
|
||||
Capture(usize, String),
|
||||
Predicate(String),
|
||||
}
|
||||
|
||||
|
|
@ -812,7 +812,9 @@ impl Query {
|
|||
if ptr.is_null() {
|
||||
let offset = error_offset as usize;
|
||||
let mut line_start = 0;
|
||||
let mut row = 0;
|
||||
let line_containing_error = source.split("\n").find_map(|line| {
|
||||
row += 1;
|
||||
let line_end = line_start + line.len() + 1;
|
||||
if line_end > offset {
|
||||
Some(line)
|
||||
|
|
@ -836,13 +838,13 @@ impl Query {
|
|||
.unwrap_or(source.len());
|
||||
let name = suffix.split_at(end_offset).0.to_string();
|
||||
match error_type {
|
||||
ffi::TSQueryError_TSQueryErrorNodeType => Err(QueryError::NodeType(name)),
|
||||
ffi::TSQueryError_TSQueryErrorField => Err(QueryError::Field(name)),
|
||||
ffi::TSQueryError_TSQueryErrorCapture => Err(QueryError::Capture(name)),
|
||||
_ => Err(QueryError::Syntax(message)),
|
||||
ffi::TSQueryError_TSQueryErrorNodeType => Err(QueryError::NodeType(row, name)),
|
||||
ffi::TSQueryError_TSQueryErrorField => Err(QueryError::Field(row, name)),
|
||||
ffi::TSQueryError_TSQueryErrorCapture => Err(QueryError::Capture(row, name)),
|
||||
_ => Err(QueryError::Syntax(row, message)),
|
||||
}
|
||||
} else {
|
||||
Err(QueryError::Syntax(message))
|
||||
Err(QueryError::Syntax(row, message))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ static TSQueryError ts_query_parse_predicate(
|
|||
// Parse the string content
|
||||
const char *string_content = stream->input;
|
||||
while (stream->next != '"') {
|
||||
if (!stream_advance(stream)) {
|
||||
if (stream->next == '\n' || !stream_advance(stream)) {
|
||||
stream_reset(stream, string_content - 1);
|
||||
return TSQueryErrorSyntax;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue