harper_core/linting/
out_of_date.rs

1use crate::{
2    Token, TokenStringExt,
3    patterns::{EitherPattern, ExactPhrase, Pattern},
4};
5
6use super::{Lint, LintKind, PatternLinter, Suggestion};
7
8pub struct OutOfDate {
9    pattern: Box<dyn Pattern>,
10}
11
12impl Default for OutOfDate {
13    fn default() -> Self {
14        let pattern = EitherPattern::new(vec![
15            Box::new(ExactPhrase::from_phrase("out of date")),
16            Box::new(ExactPhrase::from_phrase("out-of date")),
17            Box::new(ExactPhrase::from_phrase("out of-date")),
18        ]);
19
20        Self {
21            pattern: Box::new(pattern),
22        }
23    }
24}
25
26impl PatternLinter for OutOfDate {
27    fn pattern(&self) -> &dyn Pattern {
28        self.pattern.as_ref()
29    }
30
31    fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
32        let span = matched_tokens.span()?;
33        let problem_text = span.get_content(source);
34
35        Some(Lint {
36            span,
37            lint_kind: LintKind::Miscellaneous,
38            suggestions: vec![Suggestion::replace_with_match_case(
39                "out-of-date".chars().collect(),
40                problem_text,
41            )],
42            message: "Did you mean the compound adjective?".to_owned(),
43            priority: 31,
44        })
45    }
46
47    fn description(&self) -> &'static str {
48        "Ensures that the phrase `out of date` is written with a hyphen as `out-of-date` when used as a compound adjective."
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::OutOfDate;
55    use crate::linting::tests::assert_suggestion_result;
56
57    #[test]
58    fn corrects_out_of_date() {
59        assert_suggestion_result(
60            "The software is out of date.",
61            OutOfDate::default(),
62            "The software is out-of-date.",
63        );
64    }
65
66    #[test]
67    fn corrects_out_of_date_with_variation() {
68        assert_suggestion_result(
69            "This information is out of-date.",
70            OutOfDate::default(),
71            "This information is out-of-date.",
72        );
73    }
74
75    #[test]
76    fn allows_correct_usage() {
77        assert_suggestion_result(
78            "The guidelines are out-of-date.",
79            OutOfDate::default(),
80            "The guidelines are out-of-date.",
81        );
82    }
83}