Skip to content

Commit

Permalink
test: add a regression test, that prints the warning in question
Browse files Browse the repository at this point in the history
Ref #281
  • Loading branch information
drahnr committed Sep 17, 2022
1 parent 16e5e43 commit 12eb454
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 43 deletions.
89 changes: 46 additions & 43 deletions src/checker/hunspell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use std::io::{self, BufRead};
use std::path::{Path, PathBuf};
use std::sync::Arc;

use hunspell_rs::Hunspell;
use hunspell_rs::{CheckResult, Hunspell};

use crate::errors::*;

Expand Down Expand Up @@ -226,7 +226,7 @@ impl HunspellCheckerInner {

if cfg!(debug_assertions) && Lang5::en_US == lang {
// "Test" is a valid word
debug_assert!(hunspell.check("Test"));
debug_assert_eq!(hunspell.check("Test"), CheckResult::FoundInDictionary);
// suggestion must contain the word itself if it is valid
debug_assert!(hunspell.suggest("Test").contains(&"Test".to_string()));
}
Expand Down Expand Up @@ -384,48 +384,51 @@ fn obtain_suggestions<'s>(
allow_emojis: bool,
acc: &mut Vec<Suggestion<'s>>,
) {
if !hunspell.check(&word) {
log::trace!("No match for word (plain range: {:?}): >{}<", &range, &word);
// get rid of single character suggestions
let replacements = hunspell
.suggest(&word)
.into_iter()
.filter(|x| x.len() > 1) // single char suggestions tend to be useless
.collect::<Vec<_>>();

log::debug!(target: "hunspell", "{word} --{{suggest}}--> {replacements:?}");

// strings made of vulgar fraction or emoji
if allow_emojis && consists_of_vulgar_fractions_or_emojis(&word) {
log::trace!(target: "quirks", "Found emoji or vulgar fraction character, treating {} as ok", &word);
return;
}
match hunspell.check(&word) {
CheckResult::MissingInDictionary => {
log::trace!("No match for word (plain range: {:?}): >{}<", &range, &word);
// get rid of single character suggestions
let replacements = hunspell
.suggest(&word)
.into_iter()
.filter(|x| x.len() > 1) // single char suggestions tend to be useless
.collect::<Vec<_>>();

log::debug!(target: "hunspell", "{word} --{{suggest}}--> {replacements:?}");

// strings made of vulgar fraction or emoji
if allow_emojis && consists_of_vulgar_fractions_or_emojis(&word) {
log::trace!(target: "quirks", "Found emoji or vulgar fraction character, treating {} as ok", &word);
return;
}

if allow_concatenated && replacements_contain_dashless(&word, replacements.as_slice()) {
log::trace!(target: "quirks", "Found dashless word in replacement suggestions, treating {} as ok", &word);
return;
}
if allow_dashed && replacements_contain_dashed(&word, replacements.as_slice()) {
log::trace!(target: "quirks", "Found dashed word in replacement suggestions, treating {} as ok", &word);
return;
if allow_concatenated && replacements_contain_dashless(&word, replacements.as_slice()) {
log::trace!(target: "quirks", "Found dashless word in replacement suggestions, treating {} as ok", &word);
return;
}
if allow_dashed && replacements_contain_dashed(&word, replacements.as_slice()) {
log::trace!(target: "quirks", "Found dashed word in replacement suggestions, treating {} as ok", &word);
return;
}
for (range, span) in plain.find_spans(range.clone()) {
acc.push(Suggestion {
detector: Detector::Hunspell,
range,
span,
origin: origin.clone(),
replacements: replacements.clone(),
chunk,
description: Some("Possible spelling mistake found.".to_owned()),
})
}
}
for (range, span) in plain.find_spans(range.clone()) {
acc.push(Suggestion {
detector: Detector::Hunspell,
range,
span,
origin: origin.clone(),
replacements: replacements.clone(),
chunk,
description: Some("Possible spelling mistake found.".to_owned()),
})
CheckResult::FoundInDictionary => {
log::trace!(
"Found a match for word (plain range: {:?}): >{}<",
&range,
word
);
}
} else {
log::trace!(
"Found a match for word (plain range: {:?}): >{}<",
&range,
word
);
}
}

Expand Down Expand Up @@ -507,7 +510,7 @@ bar
}
}

let (dic, aff) = srcs.unwrap();
let (dic, aff) = dbg!(srcs.unwrap());

let mut hunspell = Hunspell::new(
aff.display().to_string().as_str(),
Expand All @@ -531,7 +534,7 @@ bar

println!("testing >{}< against line #{} >{}<", word, lineno, line);
// "whitespace" is a word part of our custom dictionary
assert!(hunspell.check(word));
assert_eq!(hunspell.check(word), CheckResult::FoundInDictionary);
// Technically suggestion must contain the word itself if it is valid
let suggestions = hunspell.suggest(word);
// but this is not true for i.e. `clang`
Expand Down
36 changes: 36 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ macro_rules! end2end_file_cmark {
}

mod e2e {
use std::env::temp_dir;

use super::*;

#[test]
Expand Down Expand Up @@ -252,6 +254,40 @@ struct CAPI;
);
}

// The test is insufficient. While it ought to be identical
// to calling `cargo spellcheck -vvv -j 1 foo.rs` where
// `foo.rs` has identical content, this does not exhibit the
// warning message.
#[test]
fn issue_281() {
let dict_path = temp_dir().join(uuid::Uuid::new_v4().to_string() + ".dic");
// Any of the two hypthens cause havoc
const EXTRA_DICT: &str = r###"2
"###;
let mut f = fs_err::OpenOptions::new()
.create_new(true)
.truncate(true)
.write(true)
.open(&dict_path)
.unwrap();
f.write_all(EXTRA_DICT.as_bytes()).unwrap();

end2end!(
r####"
//! ©
"####,
ContentOrigin::TestEntityRust,
0,
HunspellChecker,
HunspellConfig {
extra_dictionaries: vec![dict_path],
..Default::default()
}
);
}

#[test]
fn file_justone() {
end2end_file_rust!("demo/src/nested/justone.rs", 2);
Expand Down

0 comments on commit 12eb454

Please sign in to comment.