Added a full integration test for the summary parser (ignored for the time being)
This commit is contained in:
parent
68ebb62dbf
commit
42de0fb97a
|
@ -9,7 +9,7 @@ use errors::*;
|
||||||
|
|
||||||
mod summary;
|
mod summary;
|
||||||
|
|
||||||
pub use self::summary::{Summary, parse_summary};
|
pub use self::summary::{Summary, Link, SummaryItem, parse_summary, SectionNumber};
|
||||||
|
|
||||||
|
|
||||||
/// The object in charge of parsing the source directory into a usable
|
/// The object in charge of parsing the source directory into a usable
|
||||||
|
|
|
@ -52,10 +52,14 @@ pub fn parse_summary(summary: &str) -> Result<Summary> {
|
||||||
/// The parsed `SUMMARY.md`, specifying how the book should be laid out.
|
/// The parsed `SUMMARY.md`, specifying how the book should be laid out.
|
||||||
#[derive(Debug, Clone, Default, PartialEq)]
|
#[derive(Debug, Clone, Default, PartialEq)]
|
||||||
pub struct Summary {
|
pub struct Summary {
|
||||||
title: Option<String>,
|
/// An optional title for the `SUMMARY.md`, currently just ignored.
|
||||||
prefix_chapters: Vec<SummaryItem>,
|
pub title: Option<String>,
|
||||||
numbered_chapters: Vec<SummaryItem>,
|
/// Chapters before the main text (e.g. an introduction).
|
||||||
suffix_chapters: Vec<SummaryItem>,
|
pub prefix_chapters: Vec<SummaryItem>,
|
||||||
|
/// The main chapters in the document.
|
||||||
|
pub numbered_chapters: Vec<SummaryItem>,
|
||||||
|
/// Items which come after the main document (e.g. a conclusion).
|
||||||
|
pub suffix_chapters: Vec<SummaryItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct representing an entry in the `SUMMARY.md`, possibly with nested
|
/// A struct representing an entry in the `SUMMARY.md`, possibly with nested
|
||||||
|
@ -63,15 +67,21 @@ pub struct Summary {
|
||||||
///
|
///
|
||||||
/// This is roughly the equivalent of `[Some section](./path/to/file.md)`.
|
/// This is roughly the equivalent of `[Some section](./path/to/file.md)`.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
struct Link {
|
pub struct Link {
|
||||||
name: String,
|
/// The name of the chapter.
|
||||||
location: PathBuf,
|
pub name: String,
|
||||||
number: Option<SectionNumber>,
|
/// The location of the chapter's source file, taking the book's `src`
|
||||||
nested_items: Vec<SummaryItem>,
|
/// directory as the root.
|
||||||
|
pub location: PathBuf,
|
||||||
|
/// The section number, if this chapter is in the numbered section.
|
||||||
|
pub number: Option<SectionNumber>,
|
||||||
|
/// Any nested items this chapter may contain.
|
||||||
|
pub nested_items: Vec<SummaryItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Link {
|
impl Link {
|
||||||
fn new<S: Into<String>, P: AsRef<Path>>(name: S, location: P) -> Link {
|
/// Create a new link with no nested items.
|
||||||
|
pub fn new<S: Into<String>, P: AsRef<Path>>(name: S, location: P) -> Link {
|
||||||
Link {
|
Link {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
location: location.as_ref().to_path_buf(),
|
location: location.as_ref().to_path_buf(),
|
||||||
|
@ -92,9 +102,12 @@ impl Default for Link {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An item in `SUMMARY.md` which could be either a separator or a `Link`.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
enum SummaryItem {
|
pub enum SummaryItem {
|
||||||
|
/// A link to a chapter.
|
||||||
Link(Link),
|
Link(Link),
|
||||||
|
/// A separator (`---`).
|
||||||
Separator,
|
Separator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,13 +206,20 @@ impl<'a> SummaryParser<'a> {
|
||||||
fn parse(mut self) -> Result<Summary> {
|
fn parse(mut self) -> Result<Summary> {
|
||||||
self.summary.title = self.parse_title();
|
self.summary.title = self.parse_title();
|
||||||
|
|
||||||
|
if let Some(ref title) = self.summary.title {
|
||||||
|
debug!("[*] Title is {:?}", title);
|
||||||
|
}
|
||||||
|
|
||||||
|
while self.state != State::End {
|
||||||
|
self.step()?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(self.summary)
|
Ok(self.summary)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self) -> Result<()> {
|
fn step(&mut self) -> Result<()> {
|
||||||
let next_event = self.stream.next().expect("TODO: error-chain");
|
let next_event = self.stream.next().expect("TODO: error-chain");
|
||||||
trace!("[*] Current state = {:?}, Next Event = {:?}", self.state, next_event);
|
trace!("[*] Current state: {:?}, next event: {:?}", self.state, next_event);
|
||||||
println!("{:?}", next_event);
|
|
||||||
|
|
||||||
match self.state {
|
match self.state {
|
||||||
State::Begin => self.step_start(next_event)?,
|
State::Begin => self.step_start(next_event)?,
|
||||||
|
@ -253,7 +273,7 @@ impl<'a> SummaryParser<'a> {
|
||||||
},
|
},
|
||||||
|
|
||||||
other => {
|
other => {
|
||||||
debug!("[*] Skipping unexpected token in summary: {:?}", other);
|
trace!("[*] Skipping unexpected token in summary: {:?}", other);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +330,8 @@ impl<'a> SummaryParser<'a> {
|
||||||
Event::Start(Tag::Item) => {
|
Event::Start(Tag::Item) => {
|
||||||
let it = self.parse_item()
|
let it = self.parse_item()
|
||||||
.chain_err(|| "List items should only contain links")?;
|
.chain_err(|| "List items should only contain links")?;
|
||||||
|
|
||||||
|
trace!("[*] Found a chapter: {:?}", it);
|
||||||
self.push_numbered_section(SummaryItem::Link(it));
|
self.push_numbered_section(SummaryItem::Link(it));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -379,7 +401,7 @@ fn stringify_events<'a>(events: Vec<Event<'a>>) -> String {
|
||||||
|
|
||||||
/// A section number like "1.2.3", basically just a newtype'd `Vec<u32>`.
|
/// A section number like "1.2.3", basically just a newtype'd `Vec<u32>`.
|
||||||
#[derive(Debug, PartialEq, Clone, Default)]
|
#[derive(Debug, PartialEq, Clone, Default)]
|
||||||
struct SectionNumber(Vec<u32>);
|
pub struct SectionNumber(pub Vec<u32>);
|
||||||
|
|
||||||
impl Display for SectionNumber {
|
impl Display for SectionNumber {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
//! Integration tests for loading a book into memory
|
||||||
|
|
||||||
|
extern crate mdbook;
|
||||||
|
extern crate env_logger;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use mdbook::loader::{parse_summary, Link, SummaryItem, SectionNumber, Summary};
|
||||||
|
|
||||||
|
|
||||||
|
const SUMMARY: &str = "
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
[Introduction](/intro.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[A Prefix Chapter](/some_prefix.md)
|
||||||
|
|
||||||
|
- [First chapter](/chapter_1/index.md)
|
||||||
|
- [Some Subsection](/chapter_1/subsection.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[Conclusion](/conclusion.md)
|
||||||
|
";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn load_summary_md() {
|
||||||
|
env_logger::init().unwrap();
|
||||||
|
|
||||||
|
let should_be = Summary {
|
||||||
|
title: Some(String::from("Summary")),
|
||||||
|
|
||||||
|
prefix_chapters: vec![
|
||||||
|
SummaryItem::Link(Link {
|
||||||
|
name: String::from("Introduction"),
|
||||||
|
location: PathBuf::from("/intro.md"),
|
||||||
|
number: None,
|
||||||
|
nested_items: vec![],
|
||||||
|
}),
|
||||||
|
SummaryItem::Separator,
|
||||||
|
SummaryItem::Link(Link {
|
||||||
|
name: String::from("A Prefix Chapter"),
|
||||||
|
location: PathBuf::from("/some_prefix.md"),
|
||||||
|
number: None,
|
||||||
|
nested_items: vec![],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
numbered_chapters: vec![
|
||||||
|
SummaryItem::Link(Link {
|
||||||
|
name: String::from("First Chapter"),
|
||||||
|
location: PathBuf::from("/chapter_1/index.md"),
|
||||||
|
number: Some(SectionNumber(vec![1])),
|
||||||
|
nested_items: vec![
|
||||||
|
SummaryItem::Link(Link {
|
||||||
|
name: String::from("Some Subsection"),
|
||||||
|
location: PathBuf::from("/chapter_1/subsection.md"),
|
||||||
|
number: Some(SectionNumber(vec![1, 1])),
|
||||||
|
nested_items: vec![],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
suffix_chapters: vec![
|
||||||
|
SummaryItem::Separator,
|
||||||
|
SummaryItem::Link( Link {
|
||||||
|
name: String::from("Conclusion"),
|
||||||
|
location: PathBuf::from("/conclusion.md"),
|
||||||
|
number: None,
|
||||||
|
nested_items: vec![],
|
||||||
|
})
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
let got = parse_summary(SUMMARY).unwrap();
|
||||||
|
println!("{:#?}", got);
|
||||||
|
|
||||||
|
assert_eq!(got, should_be);
|
||||||
|
}
|
Loading…
Reference in New Issue