From 3a36810aa326e4c1d6fcbeea93d2b6c37cf081de Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Thu, 28 May 2020 17:41:00 +0200 Subject: [PATCH] feat/tests: better tests Also reproduces issue #1 . --- src/literalset.rs | 58 +++++++++++++++++++++++++++++++++++++++-------- src/markdown.rs | 16 +++++++++---- src/suggestion.rs | 4 ++-- src/traverse.rs | 40 ++++++++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 20 deletions(-) diff --git a/src/literalset.rs b/src/literalset.rs index 525f7f12..29130f66 100644 --- a/src/literalset.rs +++ b/src/literalset.rs @@ -379,7 +379,7 @@ impl<'s> fmt::Display for LiteralSet { /// /// Allows better display of coverage results without code duplication. #[derive(Debug, Clone)] -pub(crate) struct TrimmedLiteralRangePrint<'a>(TrimmedLiteralRef<'a>, Range); +pub(crate) struct TrimmedLiteralRangePrint<'a>(pub TrimmedLiteralRef<'a>, pub Range); impl<'a> From<(TrimmedLiteralRef<'a>, Range)> for TrimmedLiteralRangePrint<'a> { fn from(tuple: (TrimmedLiteralRef<'a>, Range)) -> Self { @@ -442,7 +442,7 @@ impl<'a> fmt::Display for TrimmedLiteralRangePrint<'a> { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; const SKIP: usize = 3; @@ -459,8 +459,8 @@ struct Vikings; Boats float, don't they?"#; - fn annotated_literals() -> Vec { - let stream = syn::parse_str::(TEST).expect("Must be valid rust"); + pub(crate) fn annotated_literals(source: &str) -> Vec { + let stream = syn::parse_str::(source).expect("Must be valid rust"); stream .into_iter() .filter_map(|x| { @@ -482,14 +482,22 @@ struct Vikings; .collect() } - #[test] - fn combine_literals() { - let literals = dbg!(annotated_literals()); + + pub(crate) fn gen_literal_set(source: &str) -> LiteralSet { + let literals = dbg!(annotated_literals(TEST)); let mut cls = LiteralSet::default(); for literal in literals { assert!(dbg!(&mut cls).add_adjacent(literal).is_ok()); } + cls + } + + #[test] + fn combine_literals() { + let _ = env_logger::builder().is_test(true).try_init(); + + let cls = gen_literal_set(TEST); assert_eq!(cls.len(), 3); assert_eq!(cls.to_string(), TEST_LITERALS_COMBINED.to_string()); @@ -497,9 +505,11 @@ struct Vikings; #[test] fn coverage() { - let trimmed_literals = annotated_literals(); + let _ = env_logger::builder().is_test(true).try_init(); + + let trimmed_literals = annotated_literals(TEST); let range = EXMALIBU_START..EXMALIBU_END; - let (literals, start, _end) = + let (literals, _start, _end) = dbg!(find_coverage(trimmed_literals.as_slice(), &range)).unwrap(); let literal = literals.first().expect("Must be at least one literal"); let range_for_raw_str = Range { @@ -508,4 +518,34 @@ struct Vikings; }; assert_eq!(&TEST[range_for_raw_str], &literal.as_untrimmed_str()[range]); } + + + macro_rules! test_raw { + ($test: ident $(, $literal: literal)+ ; $range: expr, $expected: literal) => { + #[test] + fn $test() { + const TEST: &str = concat!("" $(, "///", $literal, "\n")+ , "struct X;"); + const START: usize = 3; + let end: usize = START + vec![$($literal.len()),* ].into_iter().fold(0usize, |acc, x| acc + x); + let literals = annotated_literals(TEST); + + let range: Range = $range; + + let (literals, _start, _end) = + find_coverage(literals.as_slice(), &range).expect("Must find coverage"); + let literal = literals.first().expect("Must be at least one literal"); + let range_for_raw_str = Range { + start: range.start + START, + end: range.end + START, + }; + + assert_eq!(&TEST[range_for_raw_str.clone()], &literal.as_untrimmed_str()[$range]); + assert_eq!(&TEST[range_for_raw_str], $expected); + } + }; + } + + test_raw!(raw_extract_0, " livelyness", " yyy" ; 2..6, "ivel"); + test_raw!(raw_extract_1, " + 12 + x0" ; 9..10, "0"); + } diff --git a/src/markdown.rs b/src/markdown.rs index 252647b3..2870245c 100644 --- a/src/markdown.rs +++ b/src/markdown.rs @@ -158,10 +158,13 @@ impl<'a> PlainOverlay<'a> { end: min(md.end, plain_range.end + offset), }; trace!( - "linear range to spans: convert reduced={:?} -> raw={:?}", + "convert (offset = {}): convert reduced={:?} -> raw={:?}", + offset, plain, md ); + let extracted = Range { start: plain_range.start + 1, end: plain_range.end + 1 }; + if extracted.start < extracted.end { let resolved = self.raw.linear_range_to_spans(extracted.clone()); trace!("linear range to spans: {:?} -> {:?}", extracted, resolved); @@ -291,11 +294,14 @@ And a line, or a rule. "##; #[test] - fn markdown_to_plain_with_mapping() { - let (plain, mapping) = PlainOverlay::extract_plain_with_mapping(MARKDOWN); + fn markdown_reduction_mapping() { + let (reduced, mapping) = PlainOverlay::extract_plain_with_mapping(MARKDOWN); - assert_eq!(dbg!(plain).as_str(), PLAIN); - assert_eq!(dbg!(mapping).len(), 19); + assert_eq!(dbg!(&reduced).as_str(), PLAIN); + assert_eq!(dbg!(&mapping).len(), 19); + for (reduced_range, markdown_range) in mapping.iter() { + assert_eq!(reduced[reduced_range.clone()], MARKDOWN[markdown_range.clone()]); + } } #[test] diff --git a/src/suggestion.rs b/src/suggestion.rs index 21692556..bbfef557 100644 --- a/src/suggestion.rs +++ b/src/suggestion.rs @@ -235,7 +235,7 @@ impl<'s> fmt::Display for Suggestion<'s> { impl<'s> fmt::Debug for Suggestion<'s> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { use crate::literalset::TrimmedLiteralRangePrint; - TrimmedLiteralRangePrint::from((self.literal, self.span.start.column..self.span.end.column)) - .fmt(formatter) + let printable = TrimmedLiteralRangePrint::from((self.literal, self.span.start.column..self.span.end.column)); + write!(formatter, "({}, {:?})", &printable, printable.1) } } diff --git a/src/traverse.rs b/src/traverse.rs index 1054b92b..d9a06d56 100644 --- a/src/traverse.rs +++ b/src/traverse.rs @@ -317,8 +317,40 @@ mod tests { ); } - // #[test] - // fn module_doc() { - // let _ = env_logger::try_init(); - // } + + // use crate::literalset::tests::{annotated_literals,gen_literal_set}; + use std::fmt::Display; + + #[cfg(feature="hunspell")] + #[test] + fn end2end() { + let _ = env_logger::try_init(); + + let source = +r#"/// A headline. +/// +/// Erronbeous **bold** __uetchkp__ +struct X"#; + + let config = crate::config::Config::default(); + let stream = syn::parse_str::(source).expect("Must parse just fine"); + let path = PathBuf::from("/tmp/virtual"); + let docs = crate::documentation::Documentation::from((&path, stream)); + + let suggestions = dbg!(crate::checker::check(&docs, &config)).expect("Must not error"); + let (path2, literal_set) = docs.iter().next().expect("Must contain exactly one"); + assert_eq!(&path, path2); + + let mut it = suggestions.iter(); + + let mut expected = |word: &'static str| { + let suggestion = it.next().expect("Must contain one missspelled word"); + let range = suggestion.span.start.column .. suggestion.span.end.column; + assert_eq!(word, &suggestion.literal.as_ref().as_untrimmed_str()[range]); + println!("Found word >> {} <<", word); + }; + + expected("Erronbeous"); + expected("uetchkp"); + } }