use vexy_json::{parse, Value};
#[test]
fn test_basic_string_types() {
assert_eq!(parse("''").unwrap(), Value::String("".to_string()));
assert_eq!(parse(r#""""#).unwrap(), Value::String("".to_string()));
assert_eq!(parse("'a'").unwrap(), Value::String("a".to_string()));
assert_eq!(parse(r#""a""#).unwrap(), Value::String("a".to_string()));
assert_eq!(parse("'a b'").unwrap(), Value::String("a b".to_string()));
assert_eq!(parse(r#""a b""#).unwrap(), Value::String("a b".to_string()));
}
#[test]
fn test_string_escape_sequences() {
assert_eq!(parse(r#""\n""#).unwrap(), Value::String("\n".to_string()));
assert_eq!(parse(r#""\t""#).unwrap(), Value::String("\t".to_string()));
assert_eq!(parse(r#""\r""#).unwrap(), Value::String("\r".to_string()));
assert_eq!(parse(r#""\"""#).unwrap(), Value::String("\"".to_string()));
assert_eq!(parse(r#""\\""#).unwrap(), Value::String("\\".to_string()));
assert_eq!(parse(r#""/""#).unwrap(), Value::String("/".to_string()));
assert_eq!(parse(r"'a\tb'").unwrap(), Value::String("a\tb".to_string()));
assert_eq!(parse(r"'a\nb'").unwrap(), Value::String("a\nb".to_string()));
}
#[test]
fn test_quote_escaping() {
assert_eq!(parse("'a\\'b'").unwrap(), Value::String("a'b".to_string()));
assert_eq!(
parse("\"a\\\"b\"").unwrap(),
Value::String("a\"b".to_string())
);
}
#[test]
fn test_unicode_escapes() {
let unicode_test = parse(r#""\u0061""#);
if unicode_test.is_ok() {
assert_eq!(unicode_test.unwrap(), Value::String("a".to_string()));
} else {
println!("vexy_json doesn't support unicode escapes - that's OK");
}
}
#[test]
fn test_string_in_objects() {
let result = parse(r#"{a: 'single', b: "double"}"#).unwrap();
if let Value::Object(map) = result {
assert_eq!(map.get("a"), Some(&Value::String("single".to_string())));
assert_eq!(map.get("b"), Some(&Value::String("double".to_string())));
} else {
panic!("Expected object with string values");
}
}
#[test]
fn test_string_in_arrays() {
let result = parse(r#"['single', "double"]"#).unwrap();
if let Value::Array(arr) = result {
assert_eq!(arr.len(), 2);
assert_eq!(arr[0], Value::String("single".to_string()));
assert_eq!(arr[1], Value::String("double".to_string()));
} else {
panic!("Expected array with string elements");
}
}
#[test]
fn test_string_error_cases() {
assert!(
parse(r#""x"#).is_err(),
"Unterminated double quote should error"
);
assert!(
parse("'x").is_err(),
"Unterminated single quote should error"
);
assert!(
parse("`test`").is_err(),
"Backtick strings should not be supported"
);
}
#[test]
fn test_newline_handling() {
let unescaped_newline_result = parse("\"\n\"");
if unescaped_newline_result.is_ok() {
println!("vexy_json allows unescaped newlines in double quotes");
} else {
println!("vexy_json errors on unescaped newlines - following JSON standard");
assert!(unescaped_newline_result.is_err());
}
assert_eq!(parse(r#""\n""#).unwrap(), Value::String("\n".to_string()));
}
#[test]
fn test_escape_edge_cases() {
let unknown_escape_result = parse(r#""\w""#);
if unknown_escape_result.is_ok() {
if let Ok(Value::String(s)) = unknown_escape_result {
println!("vexy_json handles \\w as: {s:?}");
assert!(
s == "w" || s == "\\w" || s == "\\\\w",
"Unknown escape behavior should be consistent"
);
}
} else {
println!("vexy_json errors on unknown escape sequences - that's valid behavior");
}
}
#[test]
fn test_string_edge_cases() {
assert_eq!(parse("''").unwrap(), Value::String("".to_string()));
assert_eq!(parse(r#""""#).unwrap(), Value::String("".to_string()));
assert_eq!(parse("' '").unwrap(), Value::String(" ".to_string()));
assert_eq!(parse(r#"" ""#).unwrap(), Value::String(" ".to_string()));
assert_eq!(
parse("'hello world'").unwrap(),
Value::String("hello world".to_string())
);
assert_eq!(
parse(r#""hello world""#).unwrap(),
Value::String("hello world".to_string())
);
}
#[test]
fn test_mixed_quotes_in_structures() {
let result = parse(
r#"{
single: 'value with "double" quotes',
double: "value with 'single' quotes"
}"#,
)
.unwrap();
if let Value::Object(map) = result {
assert_eq!(
map.get("single"),
Some(&Value::String("value with \"double\" quotes".to_string()))
);
assert_eq!(
map.get("double"),
Some(&Value::String("value with 'single' quotes".to_string()))
);
} else {
panic!("Expected object with mixed quote strings");
}
}
#[test]
fn test_backslash_behavior() {
let test_cases = vec![(r#""\q""#, "backslash + q"), (r#""\z""#, "backslash + z")];
for (input, description) in test_cases {
match parse(input) {
Ok(Value::String(s)) => {
println!("vexy_json handles {description} as: {s:?}");
assert!(!s.is_empty(), "String should not be empty");
}
Ok(other) => {
panic!("Expected string or error for {description}, got: {other:?}");
}
Err(_) => {
println!("vexy_json errors on {description} - that's valid behavior");
}
}
}
}