use decomment::{strip, Language, Options, Unterminated, UnterminatedKind};
fn js(source: &str) -> (String, Option<Unterminated>) {
let result = strip(source, Options::new(Language::JavaScript));
(result.output, result.unterminated)
}
#[test]
fn empty_input_gives_empty_output() {
assert_eq!(js(""), (String::new(), None));
}
#[test]
fn one_space_is_untouched() {
assert_eq!(js(" "), (" ".into(), None));
}
#[test]
fn a_lone_slash_is_not_a_comment() {
assert_eq!(js("/"), ("/".into(), None));
}
#[test]
fn a_bare_block_opener_is_deleted_and_reported() {
let (output, unterminated) = js("/*");
assert_eq!(output, "");
let open = unterminated.unwrap();
assert_eq!(open.kind, UnterminatedKind::BlockComment);
assert_eq!(open.offset, 0);
}
#[test]
fn slash_star_slash_is_unterminated_not_empty() {
let (output, unterminated) = js("/*/");
assert_eq!(output, "");
let open = unterminated.unwrap();
assert_eq!(open.kind, UnterminatedKind::BlockComment);
assert_eq!(open.offset, 0);
}
#[test]
fn the_empty_block_comment_is_a_comment() {
assert_eq!(js("/**/"), (String::new(), None));
}
#[test]
fn an_empty_block_comment_does_not_swallow_its_neighbours() {
assert_eq!(js("a/**/b"), ("ab".into(), None));
}
#[test]
fn a_block_comment_body_may_be_a_single_star() {
assert_eq!(js("a/***/b"), ("ab".into(), None));
}
#[test]
fn a_bare_line_opener_is_an_empty_comment() {
assert_eq!(js("//"), (String::new(), None));
}
#[test]
fn a_line_comment_does_not_take_its_terminator() {
assert_eq!(js("// only\n"), ("\n".into(), None));
}
#[test]
fn a_line_comment_may_end_at_end_of_input() {
assert_eq!(js("// only"), (String::new(), None));
}
#[test]
fn a_line_comment_stops_at_carriage_return_line_feed() {
assert_eq!(js("a // c\r\nb"), ("a \r\nb".into(), None));
}
#[test]
fn a_stray_block_closer_is_ordinary_text() {
assert_eq!(js("*/"), ("*/".into(), None));
}
#[test]
fn a_single_line_string_closes_at_end_of_input_without_a_report() {
assert_eq!(js("\"unterminated"), ("\"unterminated".into(), None));
}
#[test]
fn a_single_line_string_closes_at_a_line_terminator() {
assert_eq!(js("\"stray\n// gone\n"), ("\"stray\n\n".into(), None));
}
#[test]
fn an_unterminated_template_is_reported() {
let (output, unterminated) = js("`unterminated");
assert_eq!(output, "`unterminated");
let open = unterminated.unwrap();
assert_eq!(open.kind, UnterminatedKind::StringLiteral);
assert_eq!(open.offset, 0);
}
#[test]
fn a_file_that_is_one_comment_strips_to_nothing() {
assert_eq!(js("/* the whole file */"), (String::new(), None));
}
#[test]
fn a_file_with_no_comment_is_returned_unchanged() {
let source = "function f(a) { return a + 1; }\n";
assert_eq!(js(source), (source.into(), None));
}
#[test]
fn a_megabyte_of_slashes_does_not_hang() {
let source = "/".repeat(1024 * 1024);
let css = strip(&source, Options::new(Language::Css));
assert_eq!(css.output.len(), source.len());
assert_eq!(css.unterminated, None);
assert_eq!(js(&source), (String::new(), None));
}
#[test]
fn nul_bytes_are_ordinary_bytes() {
let source = "a\0b // c\0d\ne\0";
assert_eq!(js(source), ("a\0b \ne\0".into(), None));
}
#[test]
fn a_lone_block_opener_at_end_of_a_long_file_reports_its_offset() {
let mut source = "x".repeat(100_000);
source.push_str("/*");
let (output, unterminated) = js(&source);
assert_eq!(output.len(), 100_000);
let open = unterminated.unwrap();
assert_eq!(open.kind, UnterminatedKind::BlockComment);
assert_eq!(open.offset, 100_000);
}
#[test]
fn a_multi_byte_character_is_never_split() {
let source = "let s = \"héllo → wörld\"; // ünicode\n";
assert_eq!(js(source), ("let s = \"héllo → wörld\"; \n".into(), None));
}
#[test]
fn a_line_separator_ends_a_javascript_line_comment() {
assert_eq!(js("a // c\u{2028}b"), ("a \u{2028}b".into(), None));
let rust = strip("a // c\u{2028}b", Options::new(Language::Rust));
assert_eq!(rust.output, "a ");
}