feat(rulegen): support filename option (#3240)

This commit is contained in:
Dunqing 2024-05-11 14:53:48 +00:00
parent a23ba71689
commit 64cd8a9d69
2 changed files with 32 additions and 5 deletions

View file

@ -62,6 +62,7 @@ struct TestCase<'a> {
group_comment: Option<String>,
config: Option<Cow<'a, str>>,
settings: Option<Cow<'a, str>>,
filename: Option<Cow<'a, str>>,
}
impl<'a> TestCase<'a> {
@ -72,6 +73,7 @@ impl<'a> TestCase<'a> {
config: None,
settings: None,
group_comment: None,
filename: None,
};
test_case.visit_expression(arg);
test_case
@ -82,7 +84,7 @@ impl<'a> TestCase<'a> {
self
}
fn code(&self, need_config: bool, need_settings: bool) -> String {
fn code(&self, need_config: bool, need_settings: bool, need_filename: bool) -> String {
self.code
.as_ref()
.map(|code| {
@ -105,12 +107,18 @@ impl<'a> TestCase<'a> {
|| "None".to_string(),
|settings| format!(r#"Some(serde_json::json!({{ "settings": {settings} }}))"#),
);
let filename = self.filename.as_ref().map_or_else(
|| "None".to_string(),
|filename| format!(r#"Some(PathBuf::from("{filename}"))"#),
);
let code_str = if code.contains('"') {
format!("r#\"{}\"#", code.replace("\\\"", "\""))
} else {
format!("\"{code}\"")
};
if need_settings {
if need_filename {
format!("({code_str}, {config}, {settings}, {filename})")
} else if need_settings {
format!("({code_str}, {config}, {settings})")
} else if need_config {
format!("({code_str}, {config})")
@ -219,6 +227,11 @@ impl<'a> Visit<'a> for TestCase<'a> {
self.settings =
Some(Cow::Owned(json::convert_config_to_json_literal(setting_text)));
}
PropertyKey::StaticIdentifier(ident) if ident.name == "filename" => {
let span = prop.value.span();
let filename = &self.source_text[span.start as usize..span.end as usize];
self.filename = Some(Cow::Owned(filename.to_string()));
}
_ => continue,
},
ObjectPropertyKind::SpreadProperty(_) => continue,
@ -256,6 +269,7 @@ pub struct Context {
snake_rule_name: String,
pass_cases: String,
fail_cases: String,
has_filename: bool,
}
impl Context {
@ -270,8 +284,14 @@ impl Context {
snake_rule_name: underscore_rule_name,
pass_cases,
fail_cases,
has_filename: false,
}
}
fn with_filename(mut self) -> Self {
self.has_filename = true;
self
}
}
struct State<'a> {
@ -598,12 +618,16 @@ fn main() {
let fail_has_settings = fail_cases.iter().any(|case| case.settings.is_some());
let has_settings = pass_has_settings || fail_has_settings;
let pass_has_filename = pass_cases.iter().any(|case| case.filename.is_some());
let fail_has_filename = fail_cases.iter().any(|case| case.filename.is_some());
let has_filename = pass_has_filename || fail_has_filename;
let gen_cases_string = |cases: Vec<TestCase>| {
let mut codes = vec![];
let mut last_comment = String::new();
for case in cases {
let current_comment = case.group_comment();
let mut code = case.code(has_config, has_settings);
let mut code = case.code(has_config, has_settings, has_filename);
if code.is_empty() {
continue;
}
@ -613,7 +637,7 @@ fn main() {
code = format!(
"// {}\n{}",
&last_comment,
case.code(has_config, has_settings)
case.code(has_config, has_settings, has_filename)
);
}
}
@ -627,7 +651,7 @@ fn main() {
let pass_cases = gen_cases_string(pass_cases);
let fail_cases = gen_cases_string(fail_cases);
Context::new(plugin_name, &rule_name, pass_cases, fail_cases)
Context::new(plugin_name, &rule_name, pass_cases, fail_cases).with_filename()
}
Err(_err) => {
println!("Rule {rule_name} cannot be found in {rule_kind}, use empty template.");

View file

@ -39,6 +39,9 @@ impl Rule for {{pascal_rule_name}} {
#[test]
fn test() {
use crate::tester::Tester;
{{#if has_filename}}
use std::path::PathBuf;
{{/if}}
let pass = vec![
{{pass_cases}}