use crate::prelude::*;
use anyhow::Result;
use select::document::Document;
use select::predicate::{Attr, Class, Name, Predicate};
const TOC_TOP_LEVEL: &[&str] = &[
"1. With Readme",
"3. Deep Nest 1",
"Prefix 1",
"Prefix 2",
"Suffix 1",
"Suffix 2",
];
const TOC_SECOND_LEVEL: &[&str] = &[
"1.1. Nested Index",
"1.2. Nested two",
"3.1. Deep Nest 2",
"3.1.1. Deep Nest 3",
];
macro_rules! descendants {
($root:expr, $($child:expr),*) => {
$root
$(
.descendant($child)
)*
};
}
fn toc_js_html() -> Document {
let mut test = BookTest::from_dir("toc/basic_toc");
test.build();
let html = test.toc_js_html();
Document::from(html.as_str())
}
fn toc_fallback_html() -> Result<Document> {
let mut test = BookTest::from_dir("toc/basic_toc");
test.build();
let toc_path = test.dir.join("book").join("toc.html");
let html = read_to_string(toc_path);
Ok(Document::from(html.as_str()))
}
#[test]
fn check_second_toc_level() {
let doc = toc_js_html();
let mut should_be = Vec::from(TOC_SECOND_LEVEL);
should_be.sort_unstable();
let pred = descendants!(
Class("chapter"),
Name("li"),
Name("li"),
Name("a").and(Class("toggle").not())
);
let mut children_of_children: Vec<_> = doc
.find(pred)
.map(|elem| elem.text().trim().to_string())
.collect();
children_of_children.sort();
assert_eq!(children_of_children, should_be);
}
#[test]
fn check_first_toc_level() {
let doc = toc_js_html();
let mut should_be = Vec::from(TOC_TOP_LEVEL);
should_be.extend(TOC_SECOND_LEVEL);
should_be.sort_unstable();
let pred = descendants!(
Class("chapter"),
Name("li"),
Name("a").and(Class("toggle").not())
);
let mut children: Vec<_> = doc
.find(pred)
.map(|elem| elem.text().trim().to_string())
.collect();
children.sort();
assert_eq!(children, should_be);
}
#[test]
fn check_spacers() {
let doc = toc_js_html();
let should_be = 2;
let num_spacers = doc
.find(Class("chapter").descendant(Name("li").and(Class("spacer"))))
.count();
assert_eq!(num_spacers, should_be);
}
#[test]
fn check_link_target_js() {
let doc = toc_js_html();
let num_parent_links = doc
.find(
Class("chapter")
.descendant(Name("li"))
.descendant(Name("a").and(Attr("target", "_parent"))),
)
.count();
assert_eq!(num_parent_links, 0);
}
#[test]
fn check_link_target_fallback() {
let doc = toc_fallback_html().unwrap();
let num_parent_links = doc
.find(
Class("chapter")
.descendant(Name("li"))
.descendant(Name("a").and(Attr("target", "_parent"))),
)
.count();
assert_eq!(
num_parent_links,
TOC_TOP_LEVEL.len() + TOC_SECOND_LEVEL.len()
);
}
#[test]
fn summary_with_markdown_formatting() {
BookTest::from_dir("toc/summary_with_markdown_formatting")
.check_toc_js(str![[r#"
<ol class="chapter">
<li class="chapter-item expanded ">
<span class="chapter-link-wrapper">
<a href="formatted-summary.html">
<strong aria-hidden="true">1.</strong> Italic code *escape* `escape2`</a>
</span>
</li>
<li class="chapter-item expanded ">
<span class="chapter-link-wrapper">
<a href="soft.html">
<strong aria-hidden="true">2.</strong> Soft line break</a>
</span>
</li>
<li class="chapter-item expanded ">
<span class="chapter-link-wrapper">
<a href="escaped-tag.html">
<strong aria-hidden="true">3.</strong> <escaped tag></a>
</span>
</li>
</ol>
"#]])
.check_file(
"src/formatted-summary.md",
str![[r#"
# Italic code *escape* `escape2`
"#]],
)
.check_file(
"src/soft.md",
str![[r#"
# Soft line break
"#]],
)
.check_file(
"src/escaped-tag.md",
str![[r#"
# <escaped tag>
"#]],
);
}