2021-06-23 10:05:39 +00:00
|
|
|
use mdbook::book::Chapter;
|
2021-06-23 10:30:55 +00:00
|
|
|
use mdbook_toc::{Config, Toc};
|
|
|
|
use pretty_assertions::assert_eq;
|
2021-06-23 10:05:39 +00:00
|
|
|
|
|
|
|
fn default<T: Default>() -> T {
|
|
|
|
Default::default()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_marker<S: Into<String>>(marker: S) -> Config {
|
|
|
|
let mut cfg = Config::default();
|
|
|
|
cfg.marker = marker.into();
|
|
|
|
cfg
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_max_level(level: u32) -> Config {
|
|
|
|
let mut cfg = Config::default();
|
|
|
|
cfg.max_level = level;
|
|
|
|
cfg
|
|
|
|
}
|
|
|
|
|
|
|
|
trait FromContent {
|
2021-06-23 10:30:55 +00:00
|
|
|
fn from_content(content: String) -> Self;
|
2021-06-23 10:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl FromContent for Chapter {
|
2021-06-23 10:30:55 +00:00
|
|
|
fn from_content(content: String) -> Self {
|
2021-06-23 10:05:39 +00:00
|
|
|
Self {
|
|
|
|
name: "chapter".into(),
|
2021-06-23 10:30:55 +00:00
|
|
|
content,
|
2021-06-23 10:05:39 +00:00
|
|
|
number: None,
|
|
|
|
sub_items: vec![],
|
|
|
|
path: None,
|
|
|
|
source_path: None,
|
2021-06-23 10:30:55 +00:00
|
|
|
parent_names: vec![],
|
2021-06-23 10:05:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
/// Assert the Table of Content generation for an input file against the expected output file.
|
|
|
|
///
|
|
|
|
/// Reads `tests/$name.in.md` and checks the generated ToC code against `tests/$name.out.md`.
|
|
|
|
macro_rules! assert_toc {
|
|
|
|
($name:expr) => {
|
|
|
|
assert_toc!($name, default())
|
|
|
|
};
|
|
|
|
($name:expr, $config:expr) => {
|
|
|
|
let _ = env_logger::builder().is_test(true).try_init();
|
|
|
|
|
|
|
|
let config = $config;
|
|
|
|
let content = ::std::fs::read_to_string(format!("tests/{}.in.md", $name)).expect(concat!(
|
|
|
|
"Can't read ",
|
|
|
|
$name,
|
|
|
|
".in.md"
|
|
|
|
));
|
|
|
|
let expected = ::std::fs::read_to_string(format!("tests/{}.out.md", $name))
|
|
|
|
.expect(concat!("Can't read ", $name, ".out.md"));
|
|
|
|
|
|
|
|
let chapter = Chapter::from_content(content);
|
|
|
|
let result = Toc::add_toc(&chapter, &config);
|
|
|
|
match result {
|
2022-01-25 19:57:43 +00:00
|
|
|
Ok(result) => assert_eq!(expected, result),
|
2021-06-23 10:30:55 +00:00
|
|
|
Err(e) => panic!("{} failed. Error: {}", $name, e),
|
|
|
|
}
|
|
|
|
};
|
2021-06-23 10:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn adds_toc() {
|
2021-06-23 10:30:55 +00:00
|
|
|
assert_toc!("adds_toc", default());
|
2021-06-23 10:05:39 +00:00
|
|
|
}
|
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn adds_toc_with_inline_code() {
|
|
|
|
assert_toc!("with_inline_code", default());
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn leaves_tables_untouched() {
|
|
|
|
// Regression test.
|
|
|
|
// Previously we forgot to enable the same markdwon extensions as mdbook itself.
|
|
|
|
// Markdown roundtripping removes some insignificant whitespace
|
|
|
|
assert_toc!("tables_untouched");
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn handles_inline_code() {
|
|
|
|
// Regression test.
|
|
|
|
// Inline code in a header was broken up into multiple items.
|
|
|
|
// Also test for deeply nested headers.
|
|
|
|
assert_toc!("handles_inline_code");
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn multi_header_regression() {
|
|
|
|
assert_toc!("multi_header");
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn multi_header_linear_regression_3() {
|
|
|
|
assert_toc!("multi_header_linear");
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn add_toc_with_gitlab_marker() {
|
|
|
|
let marker = "[[_TOC_]]".to_owned();
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
assert_toc!("gitlab_marker", with_marker(marker));
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn unique_slugs() {
|
|
|
|
assert_toc!("unique_slugs");
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn add_toc_with_github_marker() {
|
2022-01-25 19:57:43 +00:00
|
|
|
let marker = "* auto-gen TOC:\n{:toc}\n".to_owned();
|
2021-06-23 10:30:55 +00:00
|
|
|
assert_toc!("github_marker", with_marker(marker));
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn lower_max_level() {
|
|
|
|
assert_toc!("lower_max_level", with_max_level(2));
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn higher_max_level() {
|
|
|
|
assert_toc!("higher_max_level", with_max_level(7));
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
// Regression test for [#13](https://github.com/badboy/mdbook-toc/issues/13).
|
|
|
|
// Choosing a non-HTML TOC marker breaks sites that don't use it at all,
|
|
|
|
// removed the header and first paragraph.
|
|
|
|
#[test]
|
|
|
|
fn nonhtml_marker_no_toc_in_page() {
|
|
|
|
let marker = "[[_TOC_]]".to_owned();
|
|
|
|
assert_toc!("nonhtml_marker_no_use", with_marker(marker));
|
|
|
|
}
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
#[test]
|
|
|
|
fn similar_heading_different_casing() {
|
|
|
|
// Regression test #15
|
|
|
|
// Previously we didn't use the normalized header ("slug") to decide whether to use
|
|
|
|
// different link anchors.
|
2021-06-23 10:05:39 +00:00
|
|
|
|
2021-06-23 10:30:55 +00:00
|
|
|
assert_toc!("similar_heading_different_casing");
|
|
|
|
}
|
2021-06-23 14:01:39 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn tables_with_html() {
|
|
|
|
assert_toc!("tables_with_html");
|
|
|
|
}
|
2021-08-02 16:18:49 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn backslash_escapes() {
|
|
|
|
// Regression test #21
|
|
|
|
// Backslash-escaped elements should still be escaped.
|
|
|
|
assert_toc!("backslash_escapes");
|
|
|
|
}
|