use crate::{RdDocument, RdNode, RdTag, producer};
const GENERATED: &str = "% Generated by roxygen2: do not edit by hand";
fn document(nodes: Vec<RdNode>) -> RdDocument {
RdDocument::new(nodes)
}
fn comment(text: &str) -> RdNode {
RdNode::Comment(text.into())
}
fn text(text: &str) -> RdNode {
RdNode::Text(text.into())
}
#[test]
fn recognizes_marker_and_sources() {
let doc = document(vec![
comment(GENERATED),
comment("% Please edit documentation in R/foo.R"),
]);
let view = doc.generation_header().unwrap();
assert!(view.is_generated());
assert_eq!(view.generator(), Some(&crate::RdGenerator::Roxygen2));
assert_eq!(view.source_files(), &["R/foo.R"]);
}
#[test]
fn preserves_source_order_and_wrapped_files() {
let doc = document(vec![
comment("% Please edit documentation in R/a.R, R/a.R, ./weird.R,, R/b.R"),
comment("% R/c.R, R/d.R"),
]);
assert_eq!(
doc.generation_header().unwrap().source_files(),
&["R/a.R", "R/a.R", "./weird.R", "R/b.R", "R/c.R", "R/d.R"]
);
}
#[test]
fn marker_and_source_presence_are_independent() {
let marker_document = document(vec![comment(GENERATED)]);
let marker = marker_document.generation_header().unwrap();
assert!(marker.is_generated());
assert!(!marker.has_sources());
assert!(marker.source_files().is_empty());
let source_document = document(vec![comment("% Please edit documentation in R/foo.R")]);
let source = source_document.generation_header().unwrap();
assert_eq!(source.generator(), None);
assert!(!source.is_generated());
assert!(source.has_sources());
}
#[test]
fn scans_only_the_leading_region_and_ignores_nested_comments() {
assert!(
document(vec![comment("% ordinary comment")])
.generation_header()
.is_none()
);
assert!(document(vec![]).generation_header().is_none());
assert!(
document(vec![text("not whitespace"), comment(GENERATED)])
.generation_header()
.is_none()
);
assert!(
document(vec![RdNode::tagged(
RdTag::Title,
None,
vec![comment(GENERATED)],
)])
.generation_header()
.is_none()
);
assert!(
document(vec![RdNode::group(vec![comment(GENERATED)])])
.generation_header()
.is_none()
);
let raw = RdNode::Raw(producer::raw_node(
Some("opaque".into()),
None,
vec![],
None,
vec![],
));
assert!(
document(vec![raw, comment(GENERATED)])
.generation_header()
.is_none()
);
}
#[test]
fn permits_whitespace_and_unrelated_comments_but_resets_continuations() {
let doc = document(vec![
comment(GENERATED),
text("\n \t"),
comment("% unrelated"),
text("\n"),
comment("% Please edit documentation in R/a.R"),
comment("% ordinary comment"),
comment("% R/not-a-continuation.R"),
]);
let view = doc.generation_header().unwrap();
assert!(view.is_generated());
assert_eq!(view.source_files(), &["R/a.R"]);
}
#[test]
fn generated_marker_ends_an_active_source_block() {
let doc = document(vec![
comment("% Please edit documentation in R/a.R,"),
comment(GENERATED),
comment("% R/not-a-continuation.R"),
]);
let view = doc.generation_header().unwrap();
assert_eq!(view.generator(), Some(&crate::RdGenerator::Roxygen2));
assert_eq!(view.source_files(), &["R/a.R"]);
}
#[test]
fn stops_after_non_header_content_and_rejects_near_misses() {
let unknown = document(vec![comment(
"% Generated by ROXYGEN2: do not edit by hand",
)]);
assert_eq!(
unknown.generation_header().unwrap().generator(),
Some(&crate::RdGenerator::Unknown("ROXYGEN2".into()))
);
for near_miss in [
"% contains Generated by roxygen2",
"% Generated by roxygen2: DO NOT EDIT",
"% Generated by : do not edit by hand",
"% Generated by a:b: do not edit by hand",
"% Generated by roxygen2: do not edit by hand extra",
"% Generated by roxygen2: do not edit by hand\r",
] {
assert!(
document(vec![comment(near_miss)])
.generation_header()
.is_none()
);
}
let partial = document(vec![comment(GENERATED), text("body")]);
assert!(partial.generation_header().unwrap().is_generated());
}
#[test]
fn recognizes_unknown_and_versioned_generators() {
for (marker, expected) in [
("% Generated by rdocgen: do not edit by hand", "rdocgen"),
(
"% Generated by roxygen2 (development version): do not edit by hand",
"roxygen2 (development version)",
),
] {
let doc = document(vec![comment(marker)]);
let view = doc.generation_header().unwrap();
assert_eq!(
view.generator(),
Some(&crate::RdGenerator::Unknown(expected.into()))
);
assert!(view.is_generated());
}
}
#[test]
fn multiple_markers_keep_first_generator_and_reset_sources() {
let doc = document(vec![
comment("% Please edit documentation in R/a.R,"),
comment(GENERATED),
comment("% R/not-a-continuation.R"),
comment("% Generated by rdocgen: do not edit by hand"),
comment("% R/still-not-a-continuation.R"),
]);
let view = doc.generation_header().unwrap();
assert_eq!(view.generator(), Some(&crate::RdGenerator::Roxygen2));
assert_eq!(view.source_files(), &["R/a.R"]);
}