use super::{elixir_atom_body, escape_elixir_string_literal};
const CASES: &[(&str, &str, &str)] = &[
("plain", "plain", "plain"),
("og:image", "og:image", "\"og:image\""),
("123", "123", "\"123\""),
("1foo", "1foo", "\"1foo\""),
("", "", "\"\""),
("café", "café", "\"café\""),
("has space", "has space", "\"has space\""),
("quote\"inside", "quote\\\"inside", "\"quote\\\"inside\""),
("back\\slash", "back\\\\slash", "\"back\\\\slash\""),
("interp#{1 + 1}end", "interp\\#{1 + 1}end", "\"interp\\#{1 + 1}end\""),
("hash#nointerp", "hash\\#nointerp", "\"hash\\#nointerp\""),
("ctrl\u{0}nul", "ctrl\\u{0}nul", "\"ctrl\\u{0}nul\""),
("nl\nline", "nl\\u{a}line", "\"nl\\u{a}line\""),
("tab\there", "tab\\u{9}here", "\"tab\\u{9}here\""),
("del\u{7f}", "del\\u{7f}", "\"del\\u{7f}\""),
("valid?", "valid?", "valid?"),
("valid!", "valid!", "valid!"),
("end", "end", "end"),
("a?b", "a?b", "\"a?b\""),
];
#[test]
fn escape_and_atom_body_agree_with_the_elixir_verified_table() {
for (input, expected_escaped, expected_atom_body) in CASES {
assert_eq!(
&escape_elixir_string_literal(input),
expected_escaped,
"string-literal escaping of {input:?}"
);
assert_eq!(&elixir_atom_body(input), expected_atom_body, "atom body for {input:?}");
}
}
#[test]
fn interpolation_openers_are_escaped_in_both_literal_forms() {
let payload = "x#{System.halt(1)}y";
assert_eq!(
escape_elixir_string_literal(payload),
"x\\#{System.halt(1)}y",
"the opener must be escaped as `\\#{{`, which still contains `#{{` as a substring"
);
assert_eq!(
elixir_atom_body(payload),
"\"x\\#{System.halt(1)}y\"",
"the quoted atom body carries the same escaping inside its quotes"
);
}
#[test]
fn bare_identifiers_stay_unquoted() {
for name in ["foo", "_private", "a1", "snake_case_name", "q?", "bang!"] {
assert_eq!(&elixir_atom_body(name), name, "{name} must stay a bare atom");
}
}
#[test]
fn every_invalid_atom_shape_comes_back_quoted() {
for name in [
"",
"123",
"1foo",
"café",
"has space",
"og:image",
"a?b",
"-lead",
"no!bang",
] {
let body = elixir_atom_body(name);
assert!(
body.starts_with('"') && body.ends_with('"'),
"{name:?} is not a bare Elixir identifier, so `:{name}` would be a SyntaxError; \
it must be rendered as a quoted atom, got {body}"
);
}
}