use serde_json::json;
use simple_agents_healing::prelude::*;
#[test]
fn test_markdown_variants() {
let parser = JsonishParser::new();
let input = r#"```json
{"key": "value"}
```"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
let input = r#"```
{"key": "value"}
```"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
let input = r#"```json
{"key": "value"}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
}
#[test]
fn test_trailing_comma_variants() {
let parser = JsonishParser::new();
let input = r#"{"a": 1, "b": 2,}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["a"], 1);
assert_eq!(result.value["b"], 2);
assert!(result.flags.contains(&CoercionFlag::FixedTrailingComma));
let input = r#"[1, 2, 3,]"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value[0], 1);
assert_eq!(result.value[1], 2);
assert_eq!(result.value[2], 3);
assert!(result.flags.contains(&CoercionFlag::FixedTrailingComma));
let input = r#"{"arr": [1, 2,], "obj": {"x": 1,}}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["arr"][0], 1);
assert_eq!(result.value["obj"]["x"], 1);
assert!(result.flags.contains(&CoercionFlag::FixedTrailingComma));
}
#[test]
fn test_quote_variations() {
let parser = JsonishParser::new();
let input = r#"{'key': 'value', 'num': '42'}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::FixedQuotes));
let input = r#"{"key": "value", 'other': 'test'}"#;
let result = parser.parse(input);
if let Ok(result) = result {
assert!(!result.flags.contains(&CoercionFlag::FixedQuotes));
}
}
#[test]
fn test_complex_nested_structures() {
let parser = JsonishParser::new();
let input = r#"```json
{
"user": {
"name": "Alice",
"age": 30,
"hobbies": ["reading", "coding"]
},
"metadata": {
"created": "2024-01-01",
"tags": ["important", "urgent"]
}
}
```"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["user"]["name"], "Alice");
assert_eq!(result.value["user"]["age"], 30);
assert_eq!(result.value["user"]["hobbies"][0], "reading");
assert_eq!(result.value["metadata"]["tags"][0], "important");
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
}
#[test]
fn test_confidence_scoring() {
let parser = JsonishParser::new();
let input = r#"{"key": "value"}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.confidence, 1.0);
let input = r#"```json
{"key": "value"}
```"#;
let result = parser.parse(input).unwrap();
assert!(result.confidence > 0.94 && result.confidence < 0.96);
let input = r#"```json
{"key": "value",}
```"#;
let result = parser.parse(input).unwrap();
assert!(result.confidence > 0.88 && result.confidence < 0.92);
let input = r#"```json
{'key': 'value',}
```"#;
let result = parser.parse(input).unwrap();
assert!(result.confidence > 0.80 && result.confidence < 0.90);
}
#[test]
fn test_min_confidence_threshold() {
let config = ParserConfig {
min_confidence: 0.96, ..Default::default()
};
let parser = JsonishParser::with_config(config);
let input = r#"{"key": "value"}"#;
let result = parser.parse(input);
assert!(result.is_ok());
let input = r#"```json
{"key": "value"}
```"#;
let result = parser.parse(input);
assert!(result.is_err());
match result.unwrap_err() {
simple_agent_type::error::SimpleAgentsError::Healing(HealingError::LowConfidence {
confidence,
..
}) => {
assert!(confidence < 0.96);
}
e => panic!("Expected LowConfidence error, got: {:?}", e),
}
}
#[test]
fn test_bom_variants() {
let parser = JsonishParser::new();
let input = "\u{FEFF}{\"key\": \"value\"}";
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::RemovedBom));
let input = "\u{FEFF}```json\n{\"key\": \"value\"}\n```";
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::RemovedBom));
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
}
#[test]
fn test_control_characters() {
let parser = JsonishParser::new();
let input = "{\"key\": \"val\x00ue\"}";
let result = parser.parse(input).unwrap();
assert!(result.flags.contains(&CoercionFlag::FixedControlCharacters));
}
#[test]
fn test_empty_structures() {
let parser = JsonishParser::new();
let input = r#"{}"#;
let result = parser.parse(input).unwrap();
assert!(result.value.is_object());
assert_eq!(result.value.as_object().unwrap().len(), 0);
assert_eq!(result.confidence, 1.0);
let input = r#"[]"#;
let result = parser.parse(input).unwrap();
assert!(result.value.is_array());
assert_eq!(result.value.as_array().unwrap().len(), 0);
assert_eq!(result.confidence, 1.0);
let input = r#"{,}"#;
let result = parser.parse(input);
let _ = result;
}
#[test]
fn test_large_nested_structure() {
let parser = JsonishParser::new();
let input = json!({
"level1": {
"level2": {
"level3": {
"level4": {
"level5": {
"deep": "value"
}
}
}
}
}
})
.to_string();
let result = parser.parse(&input).unwrap();
assert_eq!(
result.value["level1"]["level2"]["level3"]["level4"]["level5"]["deep"],
"value"
);
assert_eq!(result.confidence, 1.0);
}
#[test]
#[allow(clippy::approx_constant)] fn test_numeric_values() {
let parser = JsonishParser::new();
let input = r#"{
"int": 42,
"float": 3.14,
"negative": -10,
"scientific": 1.5e10,
"zero": 0
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["int"], 42);
assert_eq!(result.value["float"], 3.14);
assert_eq!(result.value["negative"], -10);
assert_eq!(result.value["scientific"], 1.5e10);
assert_eq!(result.value["zero"], 0);
}
#[test]
fn test_boolean_and_null() {
let parser = JsonishParser::new();
let input = r#"{
"true_val": true,
"false_val": false,
"null_val": null
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["true_val"], true);
assert_eq!(result.value["false_val"], false);
assert!(result.value["null_val"].is_null());
}
#[test]
fn test_unicode_strings() {
let parser = JsonishParser::new();
let input = r#"{
"emoji": "🚀 🎉",
"chinese": "ä½ å¥½",
"arabic": "Ù…Ø±ØØ¨Ø§",
"escaped": "Hello\nWorld\t!"
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["emoji"], "🚀 🎉");
assert_eq!(result.value["chinese"], "ä½ å¥½");
assert_eq!(result.value["arabic"], "Ù…Ø±ØØ¨Ø§");
assert_eq!(result.value["escaped"], "Hello\nWorld\t!");
}
#[test]
fn test_truncation_lenient_parsing() {
let parser = JsonishParser::new();
let input = r#"{"key": "value", "incomplete"#;
let result = parser.parse(input);
match result {
Ok(result) => {
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
assert!(result.confidence < 0.8);
}
Err(_) => {
}
}
}
#[test]
fn test_multiple_json_objects() {
let parser = JsonishParser::new();
let input = r#"{"first": 1} {"second": 2}"#;
let result = parser.parse(input);
if let Ok(result) = result {
assert_eq!(result.value["first"], 1);
}
}
#[test]
fn test_whitespace_variations() {
let parser = JsonishParser::new();
let input = r#"{"key":"value","num":42}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
let input = r#"{
"key": "value",
"num": 42
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
let input = r#"{ "key" : "value" , "num" : 42 }"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
}
#[test]
fn test_parser_config_customization() {
let config = ParserConfig {
strip_markdown: false,
fix_trailing_commas: false,
fix_quotes: false,
fix_unquoted_keys: false,
fix_control_chars: false,
remove_bom: false,
allow_lenient_parsing: false,
min_confidence: 0.0,
};
let parser = JsonishParser::with_config(config);
let input = r#"{"key": "value"}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
let input = r#"{"key": "value",}"#;
let result = parser.parse(input);
assert!(result.is_err());
}
#[test]
fn test_array_variations() {
let parser = JsonishParser::new();
let input = r#"[1, "two", true, null, {"key": "value"}]"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value[0], 1);
assert_eq!(result.value[1], "two");
assert_eq!(result.value[2], true);
assert!(result.value[3].is_null());
assert_eq!(result.value[4]["key"], "value");
let input = r#"[[1, 2], [3, 4], [5, 6]]"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value[0][0], 1);
assert_eq!(result.value[1][1], 4);
assert_eq!(result.value[2][0], 5);
}
#[test]
fn test_unclosed_object() {
let parser = JsonishParser::new();
let input = r#"{"name": "Alice", "age": 30"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["age"], 30);
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
}
#[test]
fn test_unclosed_array() {
let parser = JsonishParser::new();
let input = r#"[1, 2, 3, 4"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value[0], 1);
assert_eq!(result.value[3], 4);
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
}
#[test]
fn test_unclosed_string() {
let parser = JsonishParser::new();
let input = r#"{"key": "value"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["key"], "value");
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
}
#[test]
fn test_unquoted_keys() {
let parser = JsonishParser::new();
let input = r#"{name: "Alice", age: 30}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["age"], 30);
assert!(result.flags.contains(&CoercionFlag::FixedUnquotedKeys));
}
#[test]
fn test_line_comments() {
let parser = JsonishParser::new();
let input = r#"{
// This is a comment
"name": "Alice",
// Another comment
"age": 30
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["age"], 30);
}
#[test]
fn test_block_comments() {
let parser = JsonishParser::new();
let input = r#"{
/* This is a
block comment */
"name": "Alice",
/* Another one */ "age": 30
}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["age"], 30);
}
#[test]
fn test_backtick_strings() {
let parser = JsonishParser::new();
let input = r#"{"name": `Alice`, "city": `New York`}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["city"], "New York");
}
#[test]
fn test_triple_quote_strings() {
let parser = JsonishParser::new();
let input = r#"{"text": """This is
a multiline
string"""}"#;
let result = parser.parse(input).unwrap();
assert!(result.value["text"].as_str().unwrap().contains("multiline"));
}
#[test]
fn test_escape_sequences() {
let parser = JsonishParser::new();
let input = r#"{"tab": "a\tb", "newline": "a\nb", "quote": "a\"b", "backslash": "a\\b"}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["tab"].as_str().unwrap(), "a\tb");
assert_eq!(result.value["newline"].as_str().unwrap(), "a\nb");
assert_eq!(result.value["quote"].as_str().unwrap(), "a\"b");
assert_eq!(result.value["backslash"].as_str().unwrap(), "a\\b");
}
#[test]
fn test_deeply_nested_incomplete() {
let parser = JsonishParser::new();
let input = r#"{"level1": {"level2": {"value": "deep"#;
let result = parser.parse(input);
match result {
Ok(result) => {
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
assert!(result.value.is_object());
}
Err(_) => {
}
}
}
#[test]
fn test_mixed_quotes_in_values() {
let parser = JsonishParser::new();
let input = r#"{"single": 'value1', "double": "value2"}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["single"], "value1");
assert_eq!(result.value["double"], "value2");
}
#[test]
fn test_numbers_with_exponents() {
let parser = JsonishParser::new();
let input = r#"{"small": 1.5e-10, "large": 2.5e10}"#;
let result = parser.parse(input).unwrap();
assert!(result.value["small"].is_number());
assert!(result.value["large"].is_number());
}
#[test]
fn test_negative_numbers() {
let parser = JsonishParser::new();
let input = r#"{"neg_int": -42, "neg_float": -2.5}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["neg_int"], -42);
assert_eq!(result.value["neg_float"], -2.5);
}
#[test]
fn test_boolean_literals() {
let parser = JsonishParser::new();
let input = r#"{"t": true, "f": false}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["t"], true);
assert_eq!(result.value["f"], false);
}
#[test]
fn test_null_values() {
let parser = JsonishParser::new();
let input = r#"{"value": null, "another": null}"#;
let result = parser.parse(input).unwrap();
assert!(result.value["value"].is_null());
assert!(result.value["another"].is_null());
}
#[test]
fn test_empty_strings() {
let parser = JsonishParser::new();
let input = r#"{"empty": "", "another": ""}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["empty"], "");
assert_eq!(result.value["another"], "");
}
#[test]
fn test_incomplete_nested_arrays() {
let parser = JsonishParser::new();
let input = r#"[[1, 2], [3, 4"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value[0][0], 1);
assert_eq!(result.value[1][0], 3);
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
}
#[test]
fn test_incomplete_mixed_structures() {
let parser = JsonishParser::new();
let input = r#"{"items": [1, 2, 3"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["items"][0], 1);
assert_eq!(result.value["items"][2], 3);
assert!(result.flags.contains(&CoercionFlag::TruncatedJson));
}
#[test]
fn test_special_characters_in_strings() {
let parser = JsonishParser::new();
let input = r#"{"special": "!@#$%^&*()_+-=[]{}|;:,.<>?"}"#;
let result = parser.parse(input).unwrap();
assert!(result.value["special"].as_str().unwrap().contains("!@#$"));
}
#[test]
fn test_very_long_strings() {
let parser = JsonishParser::new();
let long_string = "a".repeat(1000);
let input = format!(r#"{{"long": "{}"}}"#, long_string);
let result = parser.parse(&input).unwrap();
assert_eq!(result.value["long"].as_str().unwrap().len(), 1000);
}
#[test]
fn test_multiple_trailing_commas() {
let parser = JsonishParser::new();
let input = r#"{"a": 1,}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["a"], 1);
assert!(result.flags.contains(&CoercionFlag::FixedTrailingComma));
}
#[test]
fn test_unquoted_keys_with_underscores() {
let parser = JsonishParser::new();
let input = r#"{user_name: "Alice", user_age: 30}"#;
let result = parser.parse(input).unwrap();
assert_eq!(result.value["user_name"], "Alice");
assert_eq!(result.value["user_age"], 30);
assert!(result.flags.contains(&CoercionFlag::FixedUnquotedKeys));
}
#[test]
fn test_confidence_degradation() {
let parser = JsonishParser::new();
let input1 = r#"{"key": "value"}"#;
let result1 = parser.parse(input1).unwrap();
assert_eq!(result1.confidence, 1.0);
let input2 = r#"{"key": "value",}"#;
let result2 = parser.parse(input2).unwrap();
assert!(result2.confidence < 1.0);
assert!(result2.confidence >= 0.9);
let input3 = r#"```json
{'key': 'value',}
```"#;
let result3 = parser.parse(input3).unwrap();
assert!(result3.confidence < 0.9);
}