use decomment::{strip, Language, Options, UnterminatedKind};
fn out(source: &str, language: Language) -> String {
strip(source, Options::new(language)).output
}
#[test]
fn c_has_two_comment_forms_and_two_string_forms() {
assert_eq!(out("int x = 1; // c\n", Language::C), "int x = 1; \n");
assert_eq!(out("int x = /* c */ 1;", Language::C), "int x = 1;");
assert_eq!(
out("s = \"// not\"; // yes", Language::C),
"s = \"// not\"; "
);
assert_eq!(out("c = '/'; // yes", Language::C), "c = '/'; ");
assert_eq!(
out("s = \"a\\\"// no\"; // yes", Language::C),
"s = \"a\\\"// no\"; "
);
assert_eq!(out("/* \" */ x", Language::C), " x");
}
#[test]
fn cpp_adds_raw_strings() {
let source = "auto s = R\"d(// not a comment)d\"; // yes";
assert_eq!(
out(source, Language::Cpp),
"auto s = R\"d(// not a comment)d\"; "
);
assert_eq!(
out("R\"(/* no */)\" // yes", Language::Cpp),
"R\"(/* no */)\" "
);
let result = strip("auto s = R\"d(unclosed", Options::new(Language::Cpp));
assert_eq!(
result.unterminated.unwrap().kind,
UnterminatedKind::StringLiteral
);
}
#[test]
fn csharp_adds_verbatim_strings() {
let source = "var s = @\"a // b\nc\"\"d\"; // yes";
assert_eq!(
out(source, Language::CSharp),
"var s = @\"a // b\nc\"\"d\"; "
);
assert_eq!(
out("var s = @\"x\"; /* c */", Language::CSharp),
"var s = @\"x\"; "
);
}
#[test]
fn css_has_one_comment_form() {
assert_eq!(
out("a { color: red } /* c */", Language::Css),
"a { color: red } "
);
assert_eq!(
out("a { b: '/* not */' }", Language::Css),
"a { b: '/* not */' }"
);
assert_eq!(
out("a { b: \"//\" } // kept", Language::Css),
"a { b: \"//\" } // kept"
);
assert_eq!(out("/* a /* b */ c */", Language::Css), " c */");
}
#[test]
fn go_adds_raw_backtick_strings() {
let source = "s := `a // b\nc \\ d` // yes";
assert_eq!(out(source, Language::Go), "s := `a // b\nc \\ d` ");
assert_eq!(out("s := \"//\" /* c */", Language::Go), "s := \"//\" ");
let result = strip("s := `unclosed", Options::new(Language::Go));
assert_eq!(
result.unterminated.unwrap().kind,
UnterminatedKind::StringLiteral
);
}
#[test]
fn html_strips_only_its_own_comment_form() {
assert_eq!(
out("<p>a</p><!-- c --><p>b</p>", Language::Html),
"<p>a</p><p>b</p>"
);
assert_eq!(
out("<a href=\"x\"><!-- c -->", Language::Html),
"<a href=\"x\">"
);
assert_eq!(
out("<p>a // b /* c */</p>", Language::Html),
"<p>a // b /* c */</p>"
);
let source = "<script>var x = 1; // keep</script>";
assert_eq!(out(source, Language::Html), source);
}
#[test]
fn java_adds_text_blocks() {
let source = "var s = \"\"\"\n a // b\n \"\"\"; // yes";
assert_eq!(
out(source, Language::Java),
"var s = \"\"\"\n a // b\n \"\"\"; "
);
assert_eq!(
out("char c = '/'; /* c */", Language::Java),
"char c = '/'; "
);
assert_eq!(out("/* a /* b */ c */", Language::Java), " c */");
}
#[test]
fn javascript_covers_templates_regex_and_both_quote_forms() {
assert_eq!(
out("var s = '//'; // yes", Language::JavaScript),
"var s = '//'; "
);
assert_eq!(
out("var s = \"/*\"; /* c */", Language::JavaScript),
"var s = \"/*\"; "
);
assert_eq!(
out("var t = `a // b`; // yes", Language::JavaScript),
"var t = `a // b`; "
);
assert_eq!(
out("var r = /\\/[/]/g; // yes", Language::JavaScript),
"var r = /\\/[/]/g; "
);
assert_eq!(out("/* a /* b */ c */", Language::JavaScript), " c */");
}
#[test]
fn python_has_one_comment_form_and_four_string_forms() {
assert_eq!(out("x = 1 # c\n", Language::Python), "x = 1 \n");
assert_eq!(out("s = '# not' # yes", Language::Python), "s = '# not' ");
assert_eq!(
out("s = \"# not\" # yes", Language::Python),
"s = \"# not\" "
);
assert_eq!(
out("s = '''# not\n''' # yes", Language::Python),
"s = '''# not\n''' "
);
assert_eq!(
out("s = \"\"\"# not\n\"\"\" # yes", Language::Python),
"s = \"\"\"# not\n\"\"\" "
);
assert_eq!(
out("s = r'a\\'# not' # yes", Language::Python),
"s = r'a\\'# not' "
);
let open = "s = r'a\\' # yes";
assert_eq!(out(open, Language::Python), open);
assert_eq!(
out("s = f'{x}# not' # yes", Language::Python),
"s = f'{x}# not' "
);
assert_eq!(out("x = a // b # yes", Language::Python), "x = a // b ");
}
#[test]
fn rust_covers_raw_strings_byte_strings_and_lifetimes() {
assert_eq!(out("let x = 1; // c\n", Language::Rust), "let x = 1; \n");
assert_eq!(
out("let s = r#\"a // b\"#; // yes", Language::Rust),
"let s = r#\"a // b\"#; "
);
assert_eq!(
out("let s = r\"a // b\"; // yes", Language::Rust),
"let s = r\"a // b\"; "
);
assert_eq!(
out("let s = br#\"//\"#; /* c */", Language::Rust),
"let s = br#\"//\"#; "
);
assert_eq!(
out("let b = b'/'; // yes", Language::Rust),
"let b = b'/'; "
);
assert_eq!(
out("fn f<'a>(x: &'a str) {} // yes", Language::Rust),
"fn f<'a>(x: &'a str) {} "
);
assert_eq!(
out("let c = '\\u{1F600}'; // yes", Language::Rust),
"let c = '\\u{1F600}'; "
);
assert_eq!(
out("let c = '\\n'; // yes", Language::Rust),
"let c = '\\n'; "
);
assert_eq!(
out("let s = r##\"a \"# b\"##; // yes", Language::Rust),
"let s = r##\"a \"# b\"##; "
);
}
#[test]
fn sql_uses_dash_dash_and_doubled_quotes() {
assert_eq!(
out("select 1 -- c\nfrom t", Language::Sql),
"select 1 \nfrom t"
);
assert_eq!(
out("select '-- not' -- yes", Language::Sql),
"select '-- not' "
);
assert_eq!(
out("select 'a''-- not' -- yes", Language::Sql),
"select 'a''-- not' "
);
assert_eq!(
out("select \"col--x\" /* c */", Language::Sql),
"select \"col--x\" "
);
assert_eq!(out("select 'a\\' -- yes", Language::Sql), "select 'a\\' ");
assert_eq!(out("/* a /* b */ c */", Language::Sql), " c */");
}
#[test]
fn swift_covers_raw_strings_and_nesting() {
assert_eq!(out("let x = 1 // c\n", Language::Swift), "let x = 1 \n");
assert_eq!(
out("let s = #\"a // b\"# // yes", Language::Swift),
"let s = #\"a // b\"# "
);
assert_eq!(
out("let s = ##\"a \"# b\"## // yes", Language::Swift),
"let s = ##\"a \"# b\"## "
);
assert_eq!(
out("let s = \"\"\"\na // b\n\"\"\" // yes", Language::Swift),
"let s = \"\"\"\na // b\n\"\"\" "
);
assert_eq!(
out("#if DEBUG\nlet x = 1 // yes\n#endif", Language::Swift),
"#if DEBUG\nlet x = 1 \n#endif"
);
assert_eq!(out("/* a /* b */ c */", Language::Swift), "");
}
#[test]
fn typescript_is_an_alias_of_javascript() {
let sources = [
"var re = /a//b/; var x = 1;",
"tag`raw // text`; // real",
"/* a /* b */ c */",
"let x: number = 1; // c\n",
"type T = { a: string }; /* c */",
];
for source in sources {
assert_eq!(
out(source, Language::TypeScript),
out(source, Language::JavaScript)
);
}
}
#[test]
fn the_same_text_reads_differently_per_language() {
assert_eq!(out("/* a /* b */ c */", Language::Rust), "");
assert_eq!(out("/* a /* b */ c */", Language::C), " c */");
assert_eq!(out("a -- b", Language::Sql), "a ");
assert_eq!(out("a -- b", Language::JavaScript), "a -- b");
assert_eq!(out("a // b", Language::Go), "a ");
assert_eq!(out("a // b", Language::Css), "a // b");
assert_eq!(out("a // b", Language::Html), "a // b");
assert_eq!(out("a // b", Language::Python), "a // b");
let shebang = "#!/usr/bin/env python3\nx = 1";
assert_eq!(out(shebang, Language::Python), "\nx = 1");
assert_eq!(out(shebang, Language::JavaScript), shebang);
}