use super::*;
fn md_file(dir: &tempfile::TempDir, name: &str, content: &str) -> std::path::PathBuf {
let path = dir.path().join(name);
std::fs::write(&path, content).expect("write md file");
path
}
fn hwpx_file(dir: &tempfile::TempDir, name: &str, md: &str) -> std::path::PathBuf {
let md_path = md_file(dir, &format!("_src_{name}.md"), md);
let hwpx_path = dir.path().join(name);
to_hwpx(&md_path, Some(&hwpx_path), None).expect("to_hwpx in fixture");
hwpx_path
}
#[test]
fn builder_md_to_hwpx_creates_output_file() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "doc.md", "# Hello\n\nBody.\n");
let output = dir.path().join("doc.hwpx");
ConvertOptions::new(&input, &output)
.execute()
.expect("md → hwpx must succeed");
assert!(output.exists(), "output file must be created");
check(&output).expect("output must be a valid HWPX");
}
#[test]
fn builder_hwpx_to_md_creates_output_file() {
let dir = tempfile::tempdir().unwrap();
let hwpx = hwpx_file(&dir, "doc.hwpx", "# Title\n\nParagraph.\n");
let output = dir.path().join("out.md");
ConvertOptions::new(&hwpx, &output)
.execute()
.expect("hwpx → md must succeed");
assert!(output.exists(), "output file must be created");
let content = std::fs::read_to_string(&output).unwrap();
assert!(
content.contains("Title"),
"heading must be preserved; got: {content:?}"
);
}
#[test]
fn builder_markdown_extension_alias_accepted() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "doc.markdown", "# Alias\n");
let output = dir.path().join("out.hwpx");
ConvertOptions::new(&input, &output)
.execute()
.expect(".markdown extension must be accepted");
assert!(output.exists());
}
#[test]
fn builder_md_to_md_is_rejected() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "a.md", "# Hello\n");
let output = dir.path().join("b.md");
let err = ConvertOptions::new(&input, &output)
.execute()
.expect_err("same-format pair must be rejected");
let msg = err.to_string();
assert!(
msg.contains("cannot infer conversion direction"),
"unexpected error: {msg}"
);
}
#[test]
fn builder_unknown_extension_is_rejected() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("doc.docx");
std::fs::write(&input, b"x").unwrap();
let output = dir.path().join("out.md");
let err = ConvertOptions::new(&input, &output)
.execute()
.expect_err("unknown extension must be rejected");
let msg = err.to_string();
assert!(msg.contains("cannot infer"), "unexpected error: {msg}");
}
#[test]
fn builder_refuses_overwrite_without_force() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "doc.md", "# Hi\n");
let output = dir.path().join("doc.hwpx");
std::fs::write(&output, b"existing").unwrap();
let err = ConvertOptions::new(&input, &output)
.execute()
.expect_err("must fail when output exists and force is false");
match err {
crate::error::Hwp2MdError::OutputExists { path } => {
assert_eq!(path, output, "OutputExists must carry the output path");
}
other => panic!("expected OutputExists, got: {other}"),
}
assert_eq!(std::fs::read(&output).unwrap(), b"existing");
}
#[test]
fn builder_overwrites_with_force_true() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "doc.md", "# Overwrite\n");
let output = dir.path().join("doc.hwpx");
std::fs::write(&output, b"stale content").unwrap();
ConvertOptions::new(&input, &output)
.force(true)
.execute()
.expect("must succeed when force=true");
let content = std::fs::read(&output).unwrap();
assert_ne!(
content, b"stale content",
"file must be overwritten when force=true"
);
check(&output).expect("overwritten file must be a valid HWPX");
}
#[test]
fn builder_no_force_needed_when_output_missing() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "doc.md", "# New\n");
let output = dir.path().join("doc.hwpx");
ConvertOptions::new(&input, &output)
.force(false)
.execute()
.expect("must succeed when output does not exist");
assert!(output.exists());
}
#[test]
fn builder_frontmatter_true_emits_yaml_block() {
let dir = tempfile::tempdir().unwrap();
let hwpx = hwpx_file(&dir, "doc.hwpx", "# Title\n\nBody.\n");
let output = dir.path().join("out.md");
ConvertOptions::new(&hwpx, &output)
.frontmatter(true)
.execute()
.expect("hwpx → md with frontmatter must succeed");
let content = std::fs::read_to_string(&output).unwrap();
assert!(
content.starts_with("---"),
"frontmatter=true must emit a YAML block starting with '---': {content:?}"
);
}
#[test]
fn builder_frontmatter_false_omits_yaml_block() {
let dir = tempfile::tempdir().unwrap();
let hwpx = hwpx_file(&dir, "doc.hwpx", "# Title\n\nBody.\n");
let output = dir.path().join("out.md");
ConvertOptions::new(&hwpx, &output)
.frontmatter(false)
.execute()
.expect("hwpx → md without frontmatter must succeed");
let content = std::fs::read_to_string(&output).unwrap();
assert!(
!content.starts_with("---"),
"frontmatter=false must NOT emit a YAML block: {content:?}"
);
}
#[test]
fn builder_assets_dir_is_created() {
let dir = tempfile::tempdir().unwrap();
let hwpx = hwpx_file(&dir, "doc.hwpx", "# Title\n");
let output = dir.path().join("out.md");
let assets = dir.path().join("imgs");
ConvertOptions::new(&hwpx, &output)
.assets_dir(&assets)
.execute()
.expect("hwpx → md with assets_dir must succeed");
assert!(output.exists(), "output markdown must be created");
}
#[test]
fn builder_all_options_chained_does_not_panic() {
let dir = tempfile::tempdir().unwrap();
let hwpx = hwpx_file(&dir, "doc.hwpx", "# Chain\n\nText.\n");
let output = dir.path().join("out.md");
let assets = dir.path().join("assets");
ConvertOptions::new(&hwpx, &output)
.frontmatter(true)
.assets_dir(&assets)
.force(false)
.execute()
.expect("chained builder must succeed");
assert!(output.exists());
}
#[test]
fn builder_extension_check_is_case_insensitive() {
let dir = tempfile::tempdir().unwrap();
let input = md_file(&dir, "DOC.MD", "# Upper\n");
let output = dir.path().join("OUT.HWPX");
ConvertOptions::new(&input, &output)
.execute()
.expect("upper-case extension must be accepted");
assert!(output.exists());
}
#[test]
fn builder_debug_does_not_panic() {
let dir = tempfile::tempdir().unwrap();
let input = dir.path().join("a.md");
let output = dir.path().join("b.hwpx");
let opts = ConvertOptions::new(&input, &output)
.frontmatter(true)
.force(true);
let dbg = format!("{opts:?}");
assert!(dbg.contains("ConvertOptions"), "debug output: {dbg}");
}