use proptest::prelude::*;
use proptest::test_runner::TestRunner;
fn extract_json(text: &str) -> Option<&str> {
if let Some(start) = text.find("```json") {
let rest = &text[start + 7..];
if let Some(end) = rest.find("```") {
return Some(rest[..end].trim());
}
}
if let Some(start) = text.find('{') {
if let Some(end) = text.rfind('}') {
if end > start {
return Some(&text[start..=end]);
}
}
}
None
}
#[test]
fn extract_json_never_panics() {
let mut runner = TestRunner::default();
runner
.run(&"(?s).*", |text| {
let _ = extract_json(&text);
Ok(())
})
.unwrap();
}
#[test]
fn extract_json_roundtrip_valid() {
let mut runner = TestRunner::default();
runner
.run(&"[a-zA-Z0-9\\s:.,\"\\[\\]{}_-]{10,200}", |inner| {
let json = format!("{{\"key\": \"{}\"}}", inner.replace('"', "\\\""));
let extracted = extract_json(&json);
prop_assert!(extracted.is_some());
prop_assert!(extracted.unwrap().contains("key"));
Ok(())
})
.unwrap();
}
#[test]
fn extract_json_markdown_fence() {
let text = "Some text\n```json\n{\"answer\": 42}\n```\nMore text";
assert_eq!(extract_json(text), Some(r#"{"answer": 42}"#));
}
#[test]
fn extract_json_plain_text() {
let text = r#"Preamble {"result": "success"} trailing"#;
assert_eq!(extract_json(text), Some(r#"{"result": "success"}"#));
}
#[test]
fn extract_json_no_json_returns_none() {
assert_eq!(extract_json("no json here at all"), None);
}
#[test]
fn extract_json_nested_braces() {
let text = r#"{"outer": {"inner": 42}}"#;
assert_eq!(extract_json(text), Some(text));
}
#[test]
fn extract_json_unbalanced_braces() {
let text = r#"{"key": "value""#;
assert_eq!(extract_json(text), None);
}
#[test]
fn extract_json_empty_string() {
assert_eq!(extract_json(""), None);
}
#[test]
fn extract_json_only_whitespace() {
assert_eq!(extract_json(" \n\t "), None);
}
#[test]
fn extract_json_multiple_json_objects() {
let text = r#"{"first": 1} and {"second": 2}"#;
let extracted = extract_json(text);
assert!(extracted.is_some());
assert!(extracted.unwrap().contains("first"));
assert!(extracted.unwrap().contains("second"));
}