use vexy_json::{parse, parse_with_options, ParserOptions};
#[test]
fn test_unterminated_strings() {
assert!(
parse("\"a").is_err(),
"Unterminated double quote should error"
);
assert!(
parse("\"hello").is_err(),
"Unterminated string should error"
);
assert!(
parse("'a").is_err(),
"Unterminated single quote should error"
);
assert!(
parse("'hello").is_err(),
"Unterminated single quote string should error"
);
assert!(parse("\"\"").is_ok(), "Empty double quotes should work");
assert!(parse("''").is_ok(), "Empty single quotes should work");
}
#[test]
fn test_unexpected_closing_tokens() {
assert!(parse("]").is_err(), "Unexpected ] at start should error");
assert!(parse("}").is_err(), "Unexpected }} at start should error");
assert!(
parse(" ]").is_err(),
"Unexpected ] with whitespace should error"
);
assert!(
parse(" }").is_err(),
"Unexpected }} with whitespace should error"
);
assert!(parse("[}").is_err(), "Mismatched [}} should error");
assert!(parse("{]").is_err(), "Mismatched {{] should error");
}
#[test]
fn test_unexpected_tokens_in_context() {
assert!(
parse("a]").is_err(),
"Unexpected ] after identifier should error"
);
assert!(
parse("a}").is_err(),
"Unexpected }} after identifier should error"
);
assert!(
parse("{a]").is_err(),
"Mismatched }} in object should error"
);
assert!(parse("[a}").is_err(), "Mismatched }} in array should error");
assert!(parse("{a}").is_err(), "Missing : in object should error");
assert!(
parse("{a:1]").is_err(),
"Mismatched ] in object should error"
);
}
#[test]
fn test_invalid_colon_usage() {
assert!(parse(":").is_err(), "Standalone colon should error");
assert!(parse(":a").is_err(), "Colon before value should error");
assert!(
parse(" : ").is_err(),
"Standalone colon with spaces should error"
);
assert!(parse(",:").is_err(), "Comma then colon should error");
assert!(parse(",:a").is_err(), "Comma colon value should error");
assert!(parse("[:").is_err(), "Colon in array should error");
assert!(parse("[:a").is_err(), "Colon value in array should error");
}
#[test]
fn test_invalid_comma_usage() {
assert!(
parse("{,]").is_err(),
"Comma then mismatched bracket should error"
);
assert!(
parse("[,}").is_err(),
"Comma then mismatched brace should error"
);
assert!(
parse(",}").is_err(),
"Comma then unexpected brace should error"
);
}
#[test]
fn test_valid_edge_cases() {
assert!(
parse(",]").is_err(),
"Implicit null in array not supported in vexy_json"
);
if let Ok(obj_result) = parse("{a:}") {
if let vexy_json::Value::Object(map) = obj_result {
assert_eq!(map.get("a"), Some(&vexy_json::Value::Null));
}
} else {
assert!(
parse("{a:}").is_err(),
"Trailing colon not supported in vexy_json"
);
}
assert!(parse("[]").is_ok(), "Empty array should parse");
assert!(parse("{}").is_ok(), "Empty object should parse");
assert!(parse("null").is_ok(), "Explicit null should parse");
}
#[test]
fn test_implicit_array_with_object() {
assert!(
parse("[a:1]").is_err(),
"Object notation in array not supported in vexy_json"
);
assert!(
parse("[{\"a\":1}]").is_ok(),
"Proper object in array should work"
);
assert!(parse("[1,2,3]").is_ok(), "Regular array should work");
}
#[test]
fn test_ascii_escape_errors() {
assert!(
parse("\"\\x!!\"").is_err(),
"Invalid ASCII escape should error"
);
assert!(
parse("\"\\xZZ\"").is_err(),
"Invalid ASCII hex digits should error"
);
assert!(
parse("\"\\x\"").is_err(),
"Incomplete ASCII escape should error"
);
}
#[test]
fn test_unicode_escape_errors() {
assert!(
parse("\"\\uQQQQ\"").is_err(),
"Invalid Unicode escape should error"
);
assert!(
parse("\"\\u{QQQQQQ}\"").is_err(),
"Invalid extended Unicode escape should error"
);
assert!(
parse("\"\\u\"").is_err(),
"Incomplete Unicode escape should error"
);
assert!(
parse("\"\\u123\"").is_err(),
"Short Unicode escape should error"
);
}
#[test]
fn test_unprintable_characters() {
let null_char_result = parse("\"\x00\"");
if null_char_result.is_ok() {
assert!(true, "vexy_json allows null character in string");
} else {
assert!(null_char_result.is_err(), "Null character should error");
}
assert!(parse("\"hello\"").is_ok(), "Regular string should parse");
assert!(parse("\"\"").is_ok(), "Empty string should parse");
}
#[test]
fn test_parser_options_error_behavior() {
let mut strict_opts = ParserOptions::default();
strict_opts.allow_comments = false;
strict_opts.allow_trailing_commas = false;
strict_opts.allow_single_quotes = false;
strict_opts.allow_unquoted_keys = false;
assert!(parse_with_options("//comment", strict_opts.clone()).is_err());
assert!(parse_with_options("[1,]", strict_opts.clone()).is_err());
assert!(parse_with_options("'string'", strict_opts.clone()).is_err());
assert!(parse_with_options("{key:1}", strict_opts.clone()).is_err());
}
#[test]
fn test_empty_input_edge_cases() {
assert_eq!(parse("").unwrap(), vexy_json::Value::Null);
assert_eq!(parse(" ").unwrap(), vexy_json::Value::Null);
assert_eq!(parse("\t").unwrap(), vexy_json::Value::Null);
assert_eq!(parse("\n").unwrap(), vexy_json::Value::Null);
assert_eq!(parse("\r").unwrap(), vexy_json::Value::Null);
}
#[test]
fn test_nested_structure_errors() {
assert!(
parse("{{{{").is_err(),
"Deeply nested unclosed objects should error"
);
assert!(
parse("[[[[").is_err(),
"Deeply nested unclosed arrays should error"
);
assert!(
parse("{[{[").is_err(),
"Mixed unclosed structures should error"
);
assert!(
parse("{[}]").is_err(),
"Mismatched closing in nested should error"
);
assert!(
parse("[{]})").is_err(),
"Mismatched closing in nested should error"
);
}
#[test]
fn test_number_format_errors() {
assert!(
parse("1.").is_ok(),
"Trailing decimal point should be valid"
); assert!(parse(".").is_err(), "Lone decimal point should error");
assert!(parse("..1").is_err(), "Double decimal should error");
assert!(
parse("1..1").is_err(),
"Double decimal in number should error"
);
assert!(
parse("1e").is_err(),
"Incomplete scientific notation should error"
);
assert!(
parse("1e+").is_err(),
"Incomplete scientific notation with sign should error"
);
}
#[test]
fn test_comment_error_cases() {
assert!(parse("/*").is_err(), "Unclosed block comment should error");
assert!(
parse("/* unclosed").is_err(),
"Unclosed block comment with content should error"
);
assert!(
parse("a /* unclosed").is_err(),
"Unclosed comment after content should error"
);
let comment_result = parse("/* closed */ a");
if comment_result.is_ok() {
assert!(true, "vexy_json supports comments by default");
} else {
let mut opts = ParserOptions::default();
opts.allow_comments = true;
let with_options = parse_with_options("/* closed */ a", opts);
if with_options.is_ok() {
assert!(true, "vexy_json supports comments with options");
} else {
assert!(
true,
"vexy_json does not support comments - this is valid behavior"
);
}
}
assert!(parse("a").is_ok(), "Basic identifier parsing should work");
assert!(parse("\"hello\"").is_ok(), "String parsing should work");
}