2019-05-20 04:16:10 +08:00
|
|
|
//! Integration tests to make sure alternative backends work.
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
use mdbook::config::Config;
|
|
|
|
use mdbook::MDBook;
|
2020-12-31 09:26:59 +08:00
|
|
|
use std::fs;
|
2018-07-24 01:45:01 +08:00
|
|
|
use std::path::Path;
|
|
|
|
use tempfile::{Builder as TempFileBuilder, TempDir};
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn passing_alternate_backend() {
|
2019-12-31 18:16:59 +08:00
|
|
|
let (md, _temp) = dummy_book_with_backend("passing", success_cmd(), false);
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
md.build().unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn failing_alternate_backend() {
|
2019-12-31 18:16:59 +08:00
|
|
|
let (md, _temp) = dummy_book_with_backend("failing", fail_cmd(), false);
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
md.build().unwrap_err();
|
|
|
|
}
|
|
|
|
|
2018-01-25 01:15:29 +08:00
|
|
|
#[test]
|
2019-12-31 18:16:59 +08:00
|
|
|
fn missing_backends_are_fatal() {
|
|
|
|
let (md, _temp) = dummy_book_with_backend("missing", "trduyvbhijnorgevfuhn", false);
|
|
|
|
assert!(md.build().is_err());
|
|
|
|
}
|
2018-01-25 01:15:29 +08:00
|
|
|
|
2019-12-31 18:16:59 +08:00
|
|
|
#[test]
|
|
|
|
fn missing_optional_backends_are_not_fatal() {
|
|
|
|
let (md, _temp) = dummy_book_with_backend("missing", "trduyvbhijnorgevfuhn", true);
|
2018-01-25 01:15:29 +08:00
|
|
|
assert!(md.build().is_ok());
|
|
|
|
}
|
|
|
|
|
2018-01-07 22:10:48 +08:00
|
|
|
#[test]
|
|
|
|
fn alternate_backend_with_arguments() {
|
2019-12-31 18:16:59 +08:00
|
|
|
let (md, _temp) = dummy_book_with_backend("arguments", "echo Hello World!", false);
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
md.build().unwrap();
|
|
|
|
}
|
|
|
|
|
2018-01-14 19:14:27 +08:00
|
|
|
#[test]
|
|
|
|
fn backends_receive_render_context_via_stdin() {
|
2018-03-07 21:02:06 +08:00
|
|
|
use mdbook::renderer::RenderContext;
|
2018-07-24 01:45:01 +08:00
|
|
|
use std::fs::File;
|
2018-03-07 21:02:06 +08:00
|
|
|
|
2024-02-06 01:53:50 +08:00
|
|
|
let (md, temp) = dummy_book_with_backend("cat-to-file", "renderers/myrenderer", false);
|
2018-01-14 19:14:27 +08:00
|
|
|
|
2024-02-06 01:53:50 +08:00
|
|
|
let renderers = temp.path().join("renderers");
|
|
|
|
fs::create_dir(&renderers).unwrap();
|
|
|
|
rust_exe(
|
|
|
|
&renderers,
|
|
|
|
"myrenderer",
|
|
|
|
r#"fn main() {
|
|
|
|
use std::io::Read;
|
|
|
|
let mut s = String::new();
|
|
|
|
std::io::stdin().read_to_string(&mut s).unwrap();
|
|
|
|
std::fs::write("out.txt", s).unwrap();
|
|
|
|
}"#,
|
|
|
|
);
|
|
|
|
|
|
|
|
let out_file = temp.path().join("book/out.txt");
|
2018-01-14 19:14:27 +08:00
|
|
|
|
|
|
|
assert!(!out_file.exists());
|
|
|
|
md.build().unwrap();
|
|
|
|
assert!(out_file.exists());
|
|
|
|
|
|
|
|
let got = RenderContext::from_json(File::open(&out_file).unwrap());
|
|
|
|
assert!(got.is_ok());
|
|
|
|
}
|
|
|
|
|
2020-12-31 09:26:59 +08:00
|
|
|
#[test]
|
|
|
|
fn relative_command_path() {
|
|
|
|
// Checks behavior of relative paths for the `command` setting.
|
|
|
|
let temp = TempFileBuilder::new().prefix("mdbook").tempdir().unwrap();
|
|
|
|
let renderers = temp.path().join("renderers");
|
|
|
|
fs::create_dir(&renderers).unwrap();
|
|
|
|
rust_exe(
|
|
|
|
&renderers,
|
|
|
|
"myrenderer",
|
|
|
|
r#"fn main() {
|
|
|
|
std::fs::write("output", "test").unwrap();
|
|
|
|
}"#,
|
|
|
|
);
|
|
|
|
let do_test = |cmd_path| {
|
|
|
|
let mut config = Config::default();
|
|
|
|
config
|
|
|
|
.set("output.html", toml::value::Table::new())
|
|
|
|
.unwrap();
|
|
|
|
config.set("output.myrenderer.command", cmd_path).unwrap();
|
2023-05-14 00:44:11 +08:00
|
|
|
let md = MDBook::init(temp.path())
|
2020-12-31 09:26:59 +08:00
|
|
|
.with_config(config)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
let output = temp.path().join("book/myrenderer/output");
|
|
|
|
assert!(!output.exists());
|
|
|
|
md.build().unwrap();
|
|
|
|
assert!(output.exists());
|
|
|
|
fs::remove_file(output).unwrap();
|
|
|
|
};
|
|
|
|
// Legacy paths work, relative to the output directory.
|
|
|
|
if cfg!(windows) {
|
|
|
|
do_test("../../renderers/myrenderer.exe");
|
|
|
|
} else {
|
|
|
|
do_test("../../renderers/myrenderer");
|
|
|
|
}
|
|
|
|
// Modern path, relative to the book directory.
|
|
|
|
do_test("renderers/myrenderer");
|
|
|
|
}
|
|
|
|
|
2019-12-31 18:16:59 +08:00
|
|
|
fn dummy_book_with_backend(
|
|
|
|
name: &str,
|
|
|
|
command: &str,
|
|
|
|
backend_is_optional: bool,
|
|
|
|
) -> (MDBook, TempDir) {
|
2018-03-27 07:47:37 +08:00
|
|
|
let temp = TempFileBuilder::new().prefix("mdbook").tempdir().unwrap();
|
2018-01-07 22:10:48 +08:00
|
|
|
|
|
|
|
let mut config = Config::default();
|
|
|
|
config
|
|
|
|
.set(format!("output.{}.command", name), command)
|
|
|
|
.unwrap();
|
|
|
|
|
2019-12-31 18:16:59 +08:00
|
|
|
if backend_is_optional {
|
|
|
|
config
|
|
|
|
.set(format!("output.{}.optional", name), true)
|
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
2018-01-07 22:10:48 +08:00
|
|
|
let md = MDBook::init(temp.path())
|
|
|
|
.with_config(config)
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
(md, temp)
|
|
|
|
}
|
2018-12-06 05:26:53 +08:00
|
|
|
|
|
|
|
fn fail_cmd() -> &'static str {
|
|
|
|
if cfg!(windows) {
|
|
|
|
r#"cmd.exe /c "exit 1""#
|
|
|
|
} else {
|
|
|
|
"false"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn success_cmd() -> &'static str {
|
|
|
|
if cfg!(windows) {
|
|
|
|
r#"cmd.exe /c "exit 0""#
|
|
|
|
} else {
|
|
|
|
"true"
|
|
|
|
}
|
|
|
|
}
|
2020-12-31 09:26:59 +08:00
|
|
|
|
|
|
|
fn rust_exe(temp: &Path, name: &str, src: &str) {
|
|
|
|
let rs = temp.join(name).with_extension("rs");
|
|
|
|
fs::write(&rs, src).unwrap();
|
|
|
|
let status = std::process::Command::new("rustc")
|
|
|
|
.arg(rs)
|
|
|
|
.current_dir(temp)
|
|
|
|
.status()
|
|
|
|
.expect("rustc should run");
|
|
|
|
assert!(status.success());
|
|
|
|
}
|