harper_core/linting/
out_of_date.rs1use 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}