harper_core/linting/
chock_full.rs

1use crate::{
2    Token, TokenStringExt,
3    patterns::{EitherPattern, Pattern, SequencePattern, WhitespacePattern, WordSet},
4};
5
6use super::{Lint, LintKind, PatternLinter, Suggestion};
7
8pub struct ChockFull {
9    pattern: Box<dyn Pattern>,
10}
11
12impl Default for ChockFull {
13    fn default() -> Self {
14        Self {
15            pattern: Box::new(
16                SequencePattern::default()
17                    .then(WordSet::new(&["chalk", "choke"]))
18                    .then(EitherPattern::new(vec![
19                        Box::new(WhitespacePattern),
20                        Box::new(|tok: &Token, _source: &[char]| tok.kind.is_hyphen()),
21                    ]))
22                    .then_exact_word("full"),
23            ),
24        }
25    }
26}
27
28impl PatternLinter for ChockFull {
29    fn pattern(&self) -> &dyn Pattern {
30        self.pattern.as_ref()
31    }
32
33    fn match_to_lint(&self, matched_toks: &[Token], source: &[char]) -> Option<Lint> {
34        let span = matched_toks.span()?;
35
36        Some(Lint {
37            span,
38            lint_kind: LintKind::WordChoice,
39            suggestions: vec![Suggestion::replace_with_match_case_str(
40                "chock-full",
41                span.get_content(source),
42            )],
43            message: format!(
44                "The standard term is \"chock-full\"{}.",
45                if matched_toks[1].kind.is_whitespace() {
46                    ", and it should be hyphenated"
47                } else {
48                    ""
49                }
50            ),
51            priority: 126,
52        })
53    }
54
55    fn description(&self) -> &'static str {
56        "Flags common soundalikes of \"chock-full\" and makes sure they're hyphenated."
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::ChockFull;
63    use crate::linting::tests::{assert_lint_count, assert_suggestion_result};
64
65    #[test]
66    fn allows_correct_form() {
67        assert_lint_count(
68            "'Chalk full', 'chalk-full', 'choke full', and 'choke-full' are nonstandard forms of 'chock-full'.",
69            ChockFull::default(),
70            4,
71        );
72    }
73
74    #[test]
75    fn lower_space_chalk() {
76        assert_suggestion_result(
77            "The codebase is chalk full of errors that we need to address.",
78            ChockFull::default(),
79            "The codebase is chock-full of errors that we need to address.",
80        );
81    }
82
83    #[test]
84    fn lower_space_choke() {
85        assert_suggestion_result(
86            "The project is choke full of questionable decisions that we need to revisit.",
87            ChockFull::default(),
88            "The project is chock-full of questionable decisions that we need to revisit.",
89        );
90    }
91
92    #[test]
93    fn upper_space_chalk() {
94        assert_suggestion_result(
95            "Chalk full of deprecated methods; we should refactor.",
96            ChockFull::default(),
97            "Chock-full of deprecated methods; we should refactor.",
98        );
99    }
100
101    #[test]
102    fn upper_space_choke() {
103        assert_suggestion_result(
104            "Choke full of unnecessary complexity; simplify it.",
105            ChockFull::default(),
106            "Chock-full of unnecessary complexity; simplify it.",
107        );
108    }
109
110    #[test]
111    fn lower_hyphen_chalk() {
112        assert_suggestion_result(
113            "The code is chalk-full of bugs; we need to debug before release.",
114            ChockFull::default(),
115            "The code is chock-full of bugs; we need to debug before release.",
116        );
117    }
118
119    #[test]
120    fn lower_hyphen_choke() {
121        assert_suggestion_result(
122            "The project is choke-full of warnings; we should address them.",
123            ChockFull::default(),
124            "The project is chock-full of warnings; we should address them.",
125        );
126    }
127
128    #[test]
129    fn upper_hyphen_chalk() {
130        assert_suggestion_result(
131            "Chalk-full of features, but we only need a few.",
132            ChockFull::default(),
133            "Chock-full of features, but we only need a few.",
134        );
135    }
136
137    #[test]
138    fn upper_hyphen_choke() {
139        assert_suggestion_result(
140            "Choke-full of pitfalls; let's consider alternatives.",
141            ChockFull::default(),
142            "Chock-full of pitfalls; let's consider alternatives.",
143        );
144    }
145}