use std::{
    borrow::Cow,
    string::{String, ToString as _},
};

use crate::{try_unescape, try_unescape_into, try_unescape_with, unescape_into};

#[test]
fn simple_unescape() {
    let mut buf = String::new();
    let orig = "abcdef\\gi\r\n🤣";
    try_unescape_into(&orig.escape_default().to_string(), &mut buf).unwrap();
    assert_eq!(buf, orig);
}

#[test]
fn simple_unescape_fast() {
    let mut buf = String::new();
    let orig = "abcdef\\gi\r\n🤣";
    unescape_into(&orig.escape_default().to_string(), &mut buf);
    assert_eq!(buf, orig);
}

#[test]
fn unescape_cow_owned() {
    let orig = "abcdef\\gi\r\n🤣";
    let escaped = orig.escape_default().to_string();
    let unescaped = try_unescape(&escaped).unwrap();
    assert!(matches!(unescaped, Cow::Owned(_)));
    assert_eq!(unescaped, orig);
}

#[test]
fn unescape_cow_borrowed() {
    let orig = "abcdef";
    let escaped = orig.escape_default().to_string();
    let unescaped = try_unescape(&escaped).unwrap();
    assert!(matches!(unescaped, Cow::Borrowed(_)));
    assert_eq!(unescaped, orig);
}

#[test]
fn trailing_backslash() {
    let escaped = "abc\\r\\n\\";
    assert!(try_unescape_with(escaped, |_| ()).is_err());
}

#[test]
fn vertical_tab() {
    let mut buf1 = String::new();
    let mut buf2 = String::new();
    try_unescape_into("\\v", &mut buf1).unwrap();
    try_unescape_into("\\x0B", &mut buf2).unwrap();
    assert_eq!(buf1, buf2);
}
