use expect_test::expect;
use crate::{
extract_crate_docs::rewrite_markdown::{
RewriteMarkdownOptions, code_block_fence_is_rust, rewrite_markdown,
},
markdown::Tree,
pretty_log,
};
#[test]
fn test_link() {
let markdown = "[vector](Vec)";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/alloc/vec/struct.Vec.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(result, "[vector](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)\n\n");
}
#[test]
fn test_link_autolink() {
let markdown = "[vector](Vec)";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/all oc/vec/struct.Vec<T>.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(
result,
"[vector](<https://doc.rust-lang.org/all oc/vec/struct.Vec%3CT%3E.html>)\n\n"
);
}
#[test]
fn test_reference() {
let markdown = "[Vec]";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/alloc/vec/struct.Vec.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(
result,
"[Vec]\n\n\
[Vec]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html\n"
);
}
#[test]
fn test_reference_code() {
let markdown = "[`Vec`]";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("`Vec`"),
Some(String::from("https://doc.rust-lang.org/alloc/vec/struct.Vec.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(
result,
"[`Vec`]\n\n\
[`Vec`]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html\n"
);
}
#[test]
fn test_reference_autolink() {
let markdown = "[Vec]";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/all oc/vec/struct.Vec<T>.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(
result,
"[Vec]\n\n\
[Vec]: <https://doc.rust-lang.org/all oc/vec/struct.Vec%3CT%3E.html>\n"
);
}
#[test]
fn test_reference_collapsed() {
let markdown = "[Vec][]";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/alloc/vec/struct.Vec.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(
result,
"[Vec][]\n\n\
[Vec]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html\n"
);
}
#[test]
fn test_reference_unresolved() {
let markdown = "[Vec]";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(String::from("Vec"), None)].into_iter().collect(),
..Default::default()
},
);
assert_eq!(result, "Vec\n\n");
}
#[test]
fn test_unused_definition() {
let markdown = "[Vector](Vec)";
let result = rewrite_markdown(
markdown,
&RewriteMarkdownOptions {
links: [(
String::from("Vec"),
Some(String::from("https://doc.rust-lang.org/alloc/vec/struct.Vec.html")),
)]
.into_iter()
.collect(),
..Default::default()
},
);
assert_eq!(result, "[Vector](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)\n\n");
}
#[test]
fn test_hidden_code_line() {
let markdown = "\
```\n\
// this stays\n\
# // this is ignored\n\
```";
let out = rewrite_markdown(markdown, &RewriteMarkdownOptions::default());
assert_eq!(out, "```rust\n// this stays\n```")
}
#[test]
fn test_code_block_ignore_line_fenced() {
let markdown = r#"\
```
# // ignore this line
#[derive(Debug)] // don't ignore this line
struct Foo {
foo: i32
}
# // ignore this aswell
#[derive(Debug)] // don't ignore this line
struct Bar;
let s = "foo
## bar # baz";
assert_eq!(s, "foo\n# bar # baz");
let s = "foo
### bar # baz";
assert_eq!(s, "foo\n## bar # baz");
```"#;
expect![[r#"
\
```rust
#[derive(Debug)] // don't ignore this line
struct Foo {
foo: i32
}
#[derive(Debug)] // don't ignore this line
struct Bar;
let s = "foo
# bar # baz";
assert_eq!(s, "foo\n# bar # baz");
let s = "foo
## bar # baz";
assert_eq!(s, "foo\n## bar # baz");
```"#]]
.assert_eq(&rewrite_markdown(markdown, &RewriteMarkdownOptions::default()));
}
#[test]
fn test_code_block_ignore_line_indented() {
let markdown = r#"
# // ignore this line
#[derive(Debug)] // don't ignore this line
struct Foo {
foo: i32
}
# // ignore this aswell
#[derive(Debug)] // don't ignore this line
struct Bar;
let s = "foo
## bar # baz";
assert_eq!(s, "foo\n# bar # baz");
let s = "foo
### bar # baz";
assert_eq!(s, "foo\n## bar # baz");
"#;
expect![[r#"
```rust
#[derive(Debug)] // don't ignore this line
struct Foo {
foo: i32
}
#[derive(Debug)] // don't ignore this line
struct Bar;
let s = "foo
# bar # baz";
assert_eq!(s, "foo\n# bar # baz");
let s = "foo
## bar # baz";
assert_eq!(s, "foo\n## bar # baz");
```
"#]]
.assert_eq(&rewrite_markdown(markdown, &RewriteMarkdownOptions::default()));
}
#[test]
fn test_clean_code_blocks() {
expect![[r#"
```rust
// this is rust code
let one = 1;
let two = 2;
assert_eq!(one + two, 3);
```
```rust
// this is rust code too
let one = 1;
let two = 2;
assert_eq!(one + two, 3);
```
```rust
// this is also rust code believe it or not
let one = 1;
let two = 2;
assert_eq!(one + two, 3);
```
```python
# this most certainly isn't though
def square(n):
n * n
```"#]]
.assert_eq(&rewrite_markdown(
r#"
```
// this is rust code
let one = 1;
# println!("won't show up in readme");
let two = 2;
assert_eq!(one + two, 3);
```
```compile_fail,E69420
// this is rust code too
let one = 1;
# println!("won't show up in readme");
let two = 2;
assert_eq!(one + two, 3);
```
// this is also rust code believe it or not
let one = 1;
# println!("won't show up in readme");
let two = 2;
assert_eq!(one + two, 3);
```python
# this most certainly isn't though
def square(n):
n * n
```"#,
&RewriteMarkdownOptions::default(),
));
}
#[test]
fn test_code_block_fence_is_rust() {
assert!(code_block_fence_is_rust(""));
assert!(code_block_fence_is_rust("rust"));
assert!(code_block_fence_is_rust("ignore"));
assert!(code_block_fence_is_rust("should_panic"));
assert!(code_block_fence_is_rust("no_run"));
assert!(code_block_fence_is_rust("compile_fail"));
assert!(code_block_fence_is_rust("edition"));
assert!(code_block_fence_is_rust("standalone_crate"));
assert!(code_block_fence_is_rust("ignore"));
assert!(code_block_fence_is_rust("edition2015"));
assert!(code_block_fence_is_rust("edition2018"));
assert!(code_block_fence_is_rust("edition2021"));
assert!(code_block_fence_is_rust("edition2024"));
assert!(code_block_fence_is_rust("ignore-x86_64"));
assert!(code_block_fence_is_rust("ignore-x86_64,ignore-windows"));
assert!(!code_block_fence_is_rust("c"));
}
#[test]
#[ignore = "needs to be run separately because of hooks"]
fn test_code_block_fence_error_unexpected_end() {
let out = pretty_log::tests::simple_log(|_| {
code_block_fence_is_rust("custom,{class=whoops");
});
expect![[r#"
warning: failed to parse code block language
error: invalid codeblock attribute: unexpected end
"#]]
.assert_eq(&pretty_log::tests::prepare_for_compare(&out));
}
#[test]
#[ignore = "needs to be run separately because of hooks"]
fn test_code_block_fence_error_expected_symbol() {
let out = pretty_log::tests::simple_log(|_| {
code_block_fence_is_rust("custom,{foo}");
});
expect![[r#"
warning: failed to parse code block language
error: invalid codeblock attribute: expected `=`, found `}`
"#]]
.assert_eq(&pretty_log::tests::prepare_for_compare(&out));
}
#[test]
fn test_shrink_headings() {
fn shrink_headings(markdown: &str, shrink_headings: i8) -> String {
rewrite_markdown(
markdown,
&RewriteMarkdownOptions { shrink_headings, ..Default::default() },
)
}
assert_eq!(shrink_headings("## foo", -3), "# foo");
assert_eq!(shrink_headings("## foo", -2), "# foo");
assert_eq!(shrink_headings("## foo", -1), "# foo");
assert_eq!(shrink_headings("## foo", 0), "## foo");
assert_eq!(shrink_headings("## foo", 1), "### foo");
assert_eq!(shrink_headings("## foo", 2), "#### foo");
assert_eq!(shrink_headings("## foo", 3), "##### foo");
assert_eq!(shrink_headings("## foo", 4), "###### foo");
assert_eq!(shrink_headings("## foo", 5), "###### foo");
assert_eq!(shrink_headings("## foo", 6), "###### foo");
assert_eq!(shrink_headings(" #### foo", -2), " ## foo");
}
#[test]
fn test_quoted_code_block() {
let markdown = "\
> ```\n\
> // this stays\n\
> # // this is ignored\n\
> ```";
println!("{:?}", Tree::new(markdown));
let out = rewrite_markdown(markdown, &RewriteMarkdownOptions::default());
assert_eq!(out, "> ```rust\n> // this stays\n> ```")
}
#[test]
#[ignore = "TODO"]
fn test_quoted_code_block_indented() {
let markdown = "\
> // this stays\n\
";
println!("{:?}", Tree::new(markdown));
let out = rewrite_markdown(markdown, &RewriteMarkdownOptions::default());
assert_eq!(out, "> ```rust\n> // this stays\n> ```");
}
#[test]
#[ignore = "TODO"]
fn test_quoted_code_block_indented_hidden_line() {
let markdown = "\
> // this stays\n\
> # // this is ignored\n\
";
println!("{:?}", Tree::new(markdown));
let out = rewrite_markdown(markdown, &RewriteMarkdownOptions::default());
assert_eq!(out, "> ```rust\n> // this stays\n> ```");
}