Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/cli/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static LANGUAGE_CACHE: LazyLock<DashMap<String, Arc<LanguageData>>> = LazyLock::

pub async fn check_directories(
directories: &[PathBuf],
ignore: Vec<String>,
config: String,
workspace: Option<PathBuf>,
format: bool,
Expand Down Expand Up @@ -51,6 +52,12 @@ pub async fn check_directories(
let absolute_path = path.canonicalize().expect("Path should be valid");
let uri = Url::from_file_path(&absolute_path).expect("Path should be absolute");
let language_name = util::get_language_name(&uri, &options);
if let Some(language_name) = &language_name
&& ignore.contains(language_name)
{
return None;
}

let language_data = language_name.and_then(|name| {
LANGUAGE_CACHE.get(&name).as_deref().cloned().or_else(|| {
util::get_language(&name, &options)
Expand Down
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ enum Commands {
/// Apply fixes to diagnostics that have them.
#[arg(long)]
fix: bool,

/// List of languages to be ignored, e.g. `--ignore c lua ...`.
#[arg(long, short, value_parser, num_args = 1..)]
ignore: Vec<String>,
},
/// Lint the query files in the given directories for errors. This differs from `check` because
/// it does not perform a full semantic analysis (e.g. analyzing for impossible patterns), but
Expand Down Expand Up @@ -468,14 +472,15 @@ async fn main() {
}
Some(Commands::Check {
directories,
ignore,
workspace,
config,
format,
fix,
}) => {
let config_str = get_config_str(config);
std::process::exit(
check_directories(&directories, config_str, workspace, format, fix).await,
check_directories(&directories, ignore, config_str, workspace, format, fix).await,
);
}
Some(Commands::Lint {
Expand Down
105 changes: 105 additions & 0 deletions tests/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#[cfg(test)]
mod test {
use regex::Regex;
use rstest::rstest;
use std::{
collections::{BTreeMap, HashMap},
path::Path,
process::Command,
sync::LazyLock,
};
use ts_query_ls::{Options, Predicate, PredicateParameter, SerializableRegex};

static CONFIG: LazyLock<Options> = LazyLock::new(|| Options {
valid_predicates: BTreeMap::from([
(
String::from("pred-name"),
Predicate {
description: String::from("A predicate"),
parameters: vec![PredicateParameter {
description: None,
type_: ts_query_ls::PredicateParameterType::Any,
arity: ts_query_ls::PredicateParameterArity::Variadic,
..Default::default()
}],
},
),
(
String::from("match"),
Predicate {
description: String::from("Check match"),
parameters: vec![PredicateParameter {
description: None,
type_: ts_query_ls::PredicateParameterType::Any,
arity: ts_query_ls::PredicateParameterArity::Variadic,
..Default::default()
}],
},
),
]),
valid_captures: HashMap::from([
(
String::from("after_trailing_whitespace"),
BTreeMap::from([(String::from("capture"), String::from("A capture."))]),
),
(
String::from("before_predicates"),
BTreeMap::from([(String::from("type"), String::from("A type."))]),
),
]),
language_retrieval_patterns: vec![SerializableRegex::from(
Regex::new(r"fixtures/([^/]+)").unwrap(),
)],
..Default::default()
});

#[rstest]
#[case(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/after_trailing_whitespace.scm"),
Some(["Invalid capture name \"@cap\" (fix available)"].as_slice())
)]
#[case(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_predicates.scm"),
Some(["Unrecognized predicate \"lua-match\""].as_slice())
)]
#[case(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_missing.scm"),
Some(["This pattern has no captures, and will not be processed"].as_slice())
)]
#[case(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_syntax_error.scm"),
Some(["Invalid syntax"].as_slice())
)]
#[case(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/example_test_files/simple.scm"),
None
)]
fn cli_check(#[case] path_str: &str, #[case] warning_messages: Option<&[&str]>) {
// Arrange
let path = Path::new(path_str);

// Act
let output = Command::new(env!("CARGO_BIN_EXE_ts_query_ls"))
.arg("check")
.arg(path)
.arg("--config")
.arg(serde_json::to_string::<Options>(&CONFIG).unwrap())
.arg("--ignore")
.arg("I_DO_NOT_EXIST")
.arg("example_test_files")
.output()
.expect("Failed to wait on ts-query-ls format command");

// Assert
let string_output = String::from_utf8(output.stderr).unwrap();
if let Some(messages) = warning_messages {
for message in messages {
assert!(string_output.contains(message));
}
assert_eq!(output.status.code(), Some(1));
} else {
assert_eq!(string_output, "");
assert_eq!(output.status.code(), Some(0));
}
}
}
Loading