From 15f8645bb8ec237cf14a1b46322ec124e0dc799e Mon Sep 17 00:00:00 2001 From: Yuval Shavit Date: Mon, 24 Jun 2024 22:32:44 -0400 Subject: [PATCH 1/3] add some unit tests --- src/parsing_iter.rs | 54 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/parsing_iter.rs b/src/parsing_iter.rs index 88cc4ad..a5f823b 100644 --- a/src/parsing_iter.rs +++ b/src/parsing_iter.rs @@ -139,8 +139,7 @@ impl Iterator for ParsingIterator<'_> { #[cfg(test)] mod tests { use crate::parsing_iter::{ParsingIterator, Position}; - - // TODO need more test coverage: run just this file w/ test coverage to find out what's lacking + use crate::select::ParseErrorReason; #[test] fn basic() { @@ -189,18 +188,63 @@ mod tests { fn drop_while() { let mut iter = ParsingIterator::new("A \t B"); - assert_eq!("", iter.drop_while(|ch| ch.is_whitespace())); + assert_eq!(iter.drop_while(|ch| ch.is_whitespace()), "",); next_and_check(&mut iter, Some('A'), Position { line: 0, column: 1 }); - assert_eq!(" \t ", iter.drop_while(|ch| ch.is_whitespace())); + assert_eq!(iter.drop_while(|ch| ch.is_whitespace()), " \t "); peek_and_check(&mut iter, Some('B'), Position { line: 0, column: 4 }); next_and_check(&mut iter, Some('B'), Position { line: 0, column: 5 }); - assert_eq!("", iter.drop_while(|ch| ch.is_whitespace())); + assert_eq!(iter.drop_while(|ch| ch.is_whitespace()), ""); peek_and_check(&mut iter, None, Position { line: 0, column: 5 }); next_and_check(&mut iter, None, Position { line: 0, column: 5 }); } + #[test] + fn drop_whitespace() { + let mut iter = ParsingIterator::new(" \t\r\n\t B"); + assert_eq!(iter.drop_whitespace(), " \t\r\n\t "); + assert_eq!(iter.next(), Some('B')); + } + + #[test] + fn require_whitespace() { + let mut iter = ParsingIterator::new(" BC"); + assert_eq!(iter.require_whitespace("foo"), Ok(())); + assert_eq!(iter.next(), Some('B')); + assert_eq!( + iter.require_whitespace("bar"), + Err(ParseErrorReason::InvalidSyntax( + "bar must be followed by whitespace".to_string() + )) + ); + assert_eq!(iter.next(), Some('C')); + assert_eq!(iter.require_whitespace("foo"), Ok(()),); // EOL counts as whitespace + } + + #[test] + fn require_char() { + let mut iter = ParsingIterator::new("AB"); + assert_eq!(iter.require_char('A'), Ok(())); + assert_eq!(iter.require_char('F'), Err(ParseErrorReason::Expected('F'))); + } + + #[test] + fn require_str() { + let mut iter = ParsingIterator::new("ABCD"); + assert_eq!(iter.require_str("ABC"), Ok(())); + assert_eq!(iter.require_str("FGH"), Err(ParseErrorReason::Expected('F'))); + } + + #[test] + fn consume_if() { + let mut iter = ParsingIterator::new("ABC"); + assert_eq!(iter.consume_if('A'), true); + assert_eq!(iter.position, Position { line: 0, column: 1 }); + assert_eq!(iter.consume_if('F'), false); + assert_eq!(iter.position, Position { line: 0, column: 1 }); + } + fn next_and_check(iter: &mut ParsingIterator, expect_ch: Option, expect_pos: Position) { let next_item = iter.next(); assert_eq!(next_item, expect_ch); From 306a99794e870130f75edfdbf7b0a2bc8c095705 Mon Sep 17 00:00:00 2001 From: Yuval Shavit Date: Mon, 24 Jun 2024 22:40:04 -0400 Subject: [PATCH 2/3] remove a TODO Answer: no, I can't use m_node (at least not without improving it, which isn't worth it for this). --- src/fmt_str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmt_str.rs b/src/fmt_str.rs index 4eab22a..2a5b45f 100644 --- a/src/fmt_str.rs +++ b/src/fmt_str.rs @@ -122,7 +122,7 @@ mod tests { options.constructs.math_text = true; let node = markdown::to_mdast(md, &options).unwrap(); let md_elems = MdElem::read(node, &ReadOptions::default()).unwrap(); - unwrap!(&md_elems[0], MdElem::Block(Block::LeafBlock(LeafBlock::Paragraph(p)))); // TODO can I use m_node here? + unwrap!(&md_elems[0], MdElem::Block(Block::LeafBlock(LeafBlock::Paragraph(p)))); p.body.iter().for_each(|inline| VARIANTS_CHECKER.see(inline)); let actual = inlines_to_plain_string(&p.body); assert_eq!(&actual, expect); From b51a021f21fda9f814cd4e136ab1963122fba844 Mon Sep 17 00:00:00 2001 From: Yuval Shavit Date: Mon, 24 Jun 2024 22:48:13 -0400 Subject: [PATCH 3/3] add a test --- src/fmt_md.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/fmt_md.rs b/src/fmt_md.rs index ff3ffcf..2ee105a 100644 --- a/src/fmt_md.rs +++ b/src/fmt_md.rs @@ -84,7 +84,6 @@ where // Always write the pending definitions at the end of the doc. If there were no sections, then BottomOfSection // won't have been triggered, but we still want to write them - // TODO test this specific case writer_state.write_definitions(out, DefinitionsToWrite::Both, true); } @@ -2031,6 +2030,32 @@ pub mod tests { ); } + #[test] + fn no_sections_but_writing_to_sections() { + check_render_with( + &MdOptions { + link_reference_placement: ReferencePlacement::Section, + footnote_reference_placement: ReferencePlacement::Section, + }, + md_elems![Block::LeafBlock::Paragraph { + body: vec![m_node!(Inline::Link { + text: vec![mdq_inline!("link description")], + link_definition: LinkDefinition { + url: "https://example.com".to_string(), + title: None, + reference: LinkReference::Full("1".to_string()), + }, + }),] + }], + indoc! {r#" + [link description][1] + + ----- + + [1]: https://example.com"#}, + ) + } + #[test] fn only_footnote_in_section() { check_render_with(