Skip to content

Commit b1a12f2

Browse files
committed
add more test cases
1 parent c5cdb4c commit b1a12f2

File tree

1 file changed

+65
-31
lines changed

1 file changed

+65
-31
lines changed

crates/oxc_linter/src/builder.rs

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -156,44 +156,18 @@ impl LinterBuilder {
156156

157157
pub fn with_filter(mut self, filter: LintFilter) -> Self {
158158
let (severity, filter) = filter.into();
159-
let all_rules = self.cache.borrow();
160159

161160
match severity {
162161
AllowWarnDeny::Deny | AllowWarnDeny::Warn => match filter {
163162
LintFilterKind::Category(category) => {
164-
let rules_to_configure = all_rules.iter().filter(|r| r.category() == category);
165-
for rule in rules_to_configure {
166-
if let Some(mut existing_rule) = self.rules.take(rule) {
167-
existing_rule.severity = severity;
168-
self.rules.insert(existing_rule);
169-
} else {
170-
self.rules.insert(RuleWithSeverity::new(rule.clone(), severity));
171-
}
172-
}
173-
}
174-
LintFilterKind::Rule(_, name) => {
175-
self.rules.extend(
176-
all_rules
177-
.iter()
178-
.filter(|rule| rule.name() == name)
179-
.map(|rule| RuleWithSeverity::new(rule.clone(), severity)),
180-
);
163+
self.upsert_where(severity, |r| r.category() == category);
181164
}
165+
LintFilterKind::Rule(_, name) => self.upsert_where(severity, |r| r.name() == name),
182166
LintFilterKind::Generic(name_or_category) => {
183167
if name_or_category == "all" {
184-
self.rules.extend(
185-
all_rules
186-
.iter()
187-
.filter(|rule| rule.category() != RuleCategory::Nursery)
188-
.map(|rule| RuleWithSeverity::new(rule.clone(), severity)),
189-
);
168+
self.upsert_where(severity, |r| r.category() != RuleCategory::Nursery);
190169
} else {
191-
self.rules.extend(
192-
all_rules
193-
.iter()
194-
.filter(|rule| rule.name() == name_or_category)
195-
.map(|rule| RuleWithSeverity::new(rule.clone(), severity)),
196-
);
170+
self.upsert_where(severity, |r| r.name() == name_or_category);
197171
}
198172
}
199173
},
@@ -213,11 +187,30 @@ impl LinterBuilder {
213187
}
214188
},
215189
}
216-
drop(all_rules);
217190

218191
self
219192
}
220193

194+
/// Warn/Deny a let of rules based on some predicate. Rules already in `self.rules` get
195+
/// re-configured, while those that are not are added. Affects rules where `query` returns
196+
/// `true`.
197+
fn upsert_where<F>(&mut self, severity: AllowWarnDeny, query: F)
198+
where
199+
F: Fn(&&RuleEnum) -> bool,
200+
{
201+
let all_rules = self.cache.borrow();
202+
// NOTE: we may want to warn users if they're configuring a rule that does not exist.
203+
let rules_to_configure = all_rules.iter().filter(query);
204+
for rule in rules_to_configure {
205+
if let Some(mut existing_rule) = self.rules.take(rule) {
206+
existing_rule.severity = severity;
207+
self.rules.insert(existing_rule);
208+
} else {
209+
self.rules.insert(RuleWithSeverity::new(rule.clone(), severity));
210+
}
211+
}
212+
}
213+
221214
#[must_use]
222215
pub fn build(self) -> Linter {
223216
// When a plugin gets disabled before build(), rules for that plugin aren't removed until
@@ -403,6 +396,47 @@ mod test {
403396
}
404397
}
405398

399+
// change a rule already set to "warn" to "deny"
400+
#[test]
401+
fn test_filter_deny_single_enabled_rule_on_default() {
402+
for filter_string in ["no-const-assign", "eslint/no-const-assign"] {
403+
let builder = LinterBuilder::default();
404+
let initial_rule_count = builder.rules.len();
405+
406+
let builder =
407+
builder
408+
.with_filters([LintFilter::new(AllowWarnDeny::Deny, filter_string).unwrap()]);
409+
let rule_count_after_deny = builder.rules.len();
410+
assert_eq!(initial_rule_count, rule_count_after_deny, "Changing a single rule from warn to deny should not add a new one, just modify what's already there.");
411+
412+
let no_const_assign = builder
413+
.rules
414+
.iter()
415+
.find(|r| r.plugin_name() == "eslint" && r.name() == "no-const-assign")
416+
.expect("Could not find eslint/no-const-assign after configuring it to 'deny'");
417+
assert_eq!(no_const_assign.severity, AllowWarnDeny::Deny);
418+
}
419+
}
420+
// turn on a rule that isn't configured yet and set it to "warn"
421+
// note that this is an eslint rule, a plugin that's already turned on.
422+
#[test]
423+
fn test_filter_warn_single_disabled_rule_on_default() {
424+
for filter_string in ["no-console", "eslint/no-console"] {
425+
let filter = LintFilter::new(AllowWarnDeny::Warn, filter_string).unwrap();
426+
let builder = LinterBuilder::default();
427+
// sanity check: not already turned on
428+
assert!(!builder.rules.iter().any(|r| r.name() == "no-console"));
429+
let builder = builder.with_filter(filter);
430+
let no_console = builder
431+
.rules
432+
.iter()
433+
.find(|r| r.plugin_name() == "eslint" && r.name() == "no-console")
434+
.expect("Could not find eslint/no-console after configuring it to 'warn'");
435+
436+
assert_eq!(no_console.severity, AllowWarnDeny::Warn);
437+
}
438+
}
439+
406440
#[test]
407441
fn test_filter_allow_all_then_warn() {
408442
let builder =

0 commit comments

Comments
 (0)