harper_core/linting/
was_aloud.rs

1use super::{Lint, LintKind, PatternLinter};
2use crate::Token;
3use crate::TokenStringExt;
4use crate::linting::Suggestion;
5use crate::patterns::{Pattern, SequencePattern, WordSet};
6
7pub struct WasAloud {
8    pattern: Box<dyn Pattern>,
9}
10
11impl Default for WasAloud {
12    fn default() -> Self {
13        let pattern = SequencePattern::default()
14            .then(WordSet::new(&["was", "were", "be", "been"]))
15            .then_whitespace()
16            .then_exact_word("aloud");
17
18        Self {
19            pattern: Box::new(pattern),
20        }
21    }
22}
23
24impl PatternLinter for WasAloud {
25    fn pattern(&self) -> &dyn Pattern {
26        self.pattern.as_ref()
27    }
28
29    fn match_to_lint(&self, matched_tokens: &[Token], source: &[char]) -> Option<Lint> {
30        let verb = matched_tokens[0].span.get_content_string(source);
31
32        Some(Lint {
33            span: matched_tokens.span()?,
34            lint_kind: LintKind::WordChoice,
35            suggestions: vec![Suggestion::replace_with_match_case(
36                format!("{} allowed", verb).chars().collect(),
37                matched_tokens[0].span.get_content(source),
38            )],
39            message: format!("Did you mean `{verb} allowed`?"),
40            priority: 31,
41        })
42    }
43
44    fn description(&self) -> &'static str {
45        "Ensures `was aloud` and `were aloud` are corrected to `was allowed` or `were allowed` when referring to permission."
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::WasAloud;
52    use crate::linting::tests::assert_suggestion_result;
53
54    #[test]
55    fn corrects_was_aloud() {
56        assert_suggestion_result(
57            "He was aloud to enter the room.",
58            WasAloud::default(),
59            "He was allowed to enter the room.",
60        );
61    }
62
63    #[test]
64    fn corrects_were_aloud() {
65        assert_suggestion_result(
66            "They were aloud to participate.",
67            WasAloud::default(),
68            "They were allowed to participate.",
69        );
70    }
71
72    #[test]
73    fn does_not_correct_proper_use_of_aloud() {
74        assert_suggestion_result(
75            "She read the passage aloud to the class.",
76            WasAloud::default(),
77            "She read the passage aloud to the class.",
78        );
79    }
80
81    #[test]
82    fn does_not_flag_unrelated_text() {
83        assert_suggestion_result(
84            "The concert was loud and exciting.",
85            WasAloud::default(),
86            "The concert was loud and exciting.",
87        );
88    }
89
90    #[test]
91    fn be_aloud() {
92        assert_suggestion_result(
93            "You may be aloud to enter the room.",
94            WasAloud::default(),
95            "You may be allowed to enter the room.",
96        );
97    }
98
99    #[test]
100    fn been_aloud() {
101        assert_suggestion_result(
102            "If I had been aloud to enter I would've jumped at the chance.",
103            WasAloud::default(),
104            "If I had been allowed to enter I would've jumped at the chance.",
105        );
106    }
107}