From db8e6ed8bb22a8afeefddeddfc60abd9204a4517 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Fri, 19 May 2023 18:10:20 +0300 Subject: tests: verify that Subplot reports specific errors with location Sponsored-by: author --- src/doc.rs | 8 +++--- src/html.rs | 2 +- src/md.rs | 38 ++++++++++++++++----------- subplot.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 20 deletions(-) diff --git a/src/doc.rs b/src/doc.rs index f08f795..fe263ad 100644 --- a/src/doc.rs +++ b/src/doc.rs @@ -104,20 +104,20 @@ impl Document { { let meta = Metadata::from_yaml_metadata(basedir, yamlmeta, template)?; trace!("metadata from YAML: {:#?}", meta); - let files = Self::all_files(&markdowns); + let files = Self::all_files(&markdowns)?; let doc = Document::new(subplot, markdowns, meta, files, style); trace!("Loaded from JSON OK"); Ok(doc) } - fn all_files(markdowns: &[Markdown]) -> EmbeddedFiles { + fn all_files(markdowns: &[Markdown]) -> Result { let mut files = EmbeddedFiles::default(); for md in markdowns { - for file in md.embedded_files().files() { + for file in md.embedded_files()?.files() { files.push(file.clone()); } } - files + Ok(files) } /// Construct a Document from a named file. diff --git a/src/html.rs b/src/html.rs index b39872b..d9788d9 100644 --- a/src/html.rs +++ b/src/html.rs @@ -681,7 +681,7 @@ pub enum HtmlError { /// Input contains an attempt to use a definition list in /// Markdown. - #[error("attempt to use definition lists in Markdown: {0}")] + #[error("{0}: attempt to use definition lists in Markdown")] DefinitionList(Location), /// String formatting error. This is likely a programming error. diff --git a/src/md.rs b/src/md.rs index 02a827b..02efa0c 100644 --- a/src/md.rs +++ b/src/md.rs @@ -142,16 +142,16 @@ impl Markdown { /// Find embedded files. // FIXME: this should return a result - pub fn embedded_files(&self) -> EmbeddedFiles { + pub fn embedded_files(&self) -> Result { let mut files = EmbeddedFiles::default(); for e in Self::visit(&self.html) { - if let Ok(file) = embedded_file(e) { + if let MaybeEmbeddedFile::IsFile(file) = embedded_file(e)? { files.push(file); } } - files + Ok(files) } } @@ -175,21 +175,23 @@ impl StructureElement { } } -fn embedded_file(e: &Element) -> Result { +enum MaybeEmbeddedFile { + IsFile(EmbeddedFile), + NotFile, +} + +fn embedded_file(e: &Element) -> Result { if e.tag() != ElementTag::Pre { - return Err(MdError::NotCodeBlockElement( - e.tag().name().to_string(), - e.location(), - )); + return Ok(MaybeEmbeddedFile::NotFile); } if !e.has_attr("class", "file") { - return Err(MdError::NotFile(e.location())); + return Ok(MaybeEmbeddedFile::NotFile); } let id = e.attr("id"); if id.is_none() { - return Err(MdError::NoId(e.location())); + return Ok(MaybeEmbeddedFile::NotFile); } let id = id.unwrap(); if id.value().is_none() { @@ -212,7 +214,8 @@ fn embedded_file(e: &Element) -> Result { if contents.ends_with('\n') { contents.truncate(contents.len() - 1); } - match AddNewline::parse(e.attr("add-newline"), e.location())? { + let addnl = AddNewline::parse(e.attr("add-newline"), e.location()); + match addnl? { AddNewline::No => { // Newline already isn't there. } @@ -228,7 +231,12 @@ fn embedded_file(e: &Element) -> Result { } }; - Ok(EmbeddedFile::new(id.into(), contents)) + eprintln!("ok"); + + Ok(MaybeEmbeddedFile::IsFile(EmbeddedFile::new( + id.into(), + contents, + ))) } #[derive(Debug, Eq, PartialEq, Copy, Clone)] @@ -426,7 +434,7 @@ pub enum MdError { NoIdValue(Location), /// Value ofv add-newline attribute ie not understood. - #[error("{0}: value of add-newline attirubte is not understood: {0}")] + #[error("{1}: value of add-newline attribute is not understood: {0}")] BadAddNewline(String, Location), } @@ -637,7 +645,7 @@ given ABBA fn finds_no_embedded_files_in_empty_doc() { let md = Markdown::new_from_str(Path::new(""), "").unwrap(); let files = md.embedded_files(); - assert!(files.files().is_empty()); + assert!(files.unwrap().files().is_empty()); } #[test] @@ -651,7 +659,7 @@ hello, world "#, ) .unwrap(); - let files = md.embedded_files(); + let files = md.embedded_files().unwrap(); assert_eq!(files.files().len(), 1); let file = files.files().get(0).unwrap(); assert_eq!(file.filename(), "fileid"); diff --git a/subplot.md b/subplot.md index 9929e8b..129fc8b 100644 --- a/subplot.md +++ b/subplot.md @@ -3566,3 +3566,89 @@ This is a test file. ~~~{#expected.txt .file} This is a test file. ~~~ +## Mistakes in markdown + +When there are mistakes in the markdown input, Subplot should report +the location (filename, line, column) where the mistake is, and what +the mistake is. The scenarios in this section verify that. + +### Scenario before the first heading + +_Requirement: A scenario must follow a heading._ + +Justification: the heading can be used as the title for the scenario. + +~~~scenario +given an installed subplot +given file scenario-before-heading.subplot +given file scenario-before-heading.md +when I try to run subplot docgen scenario-before-heading.subplot -o /dev/null +then command fails +then stderr contains "ERROR: scenario-before-heading.md:1:1: first scenario is before first heading" +~~~ + +~~~{#scenario-before-heading.subplot .file .yaml} +title: Foo +markdowns: + - scenario-before-heading.md +~~~ + +~~~~~~{#scenario-before-heading.md .file .markdown} +~~~scenario +~~~ +~~~~~~ + +### Attempt to use definition list + +_Requirement: Attempt to use definition lists is reported._ + +Justification: the markdown parser we use in Subplot doesn't support +them, and it would be unhelpful to not tell the user if they try to +use them. + +~~~scenario +given an installed subplot +given file dl.subplot +given file dl.md +when I try to run subplot docgen dl.subplot -o /dev/null +then command fails +then stderr contains "ERROR: dl.md:3:1: attempt to use definition lists in Markdown" +~~~ + +~~~{#dl.subplot .file .yaml} +title: Foo +markdowns: + - dl.md +~~~ + +~~~~~~{#dl.md .file .markdown} +# Foo + +Some term +: Definition of term. +~~~~~~ + +### Bad "add-newline" value + +_Requirement: Only specific values for the "add-newline" attribute are +allowed for an embedded file._ + +~~~scenario +given an installed subplot +given file add-newline.subplot +given file add-newline.md +when I try to run subplot docgen add-newline.subplot -o /dev/null +then command fails +then stderr contains "ERROR: add-newline.md:1:1: value of add-newline attribute is not understood: xyzzy" +~~~ + +~~~{#add-newline.subplot .file .yaml} +title: Foo +markdowns: + - add-newline.md +~~~ + +~~~~~~{#add-newline.md .file .markdown} +~~~{#foo.txt .file add-newline=xyzzy} +~~~ +~~~~~~ -- cgit v1.2.1