use toonconv::conversion::{convert_json_string, ConversionConfig};
use toonconv::error::ConversionError;
use serde_json::json;
#[cfg(test)]
mod string_conversion_tests {
use super::*;
#[test]
fn test_basic_object_conversion() {
let config = ConversionConfig::default();
let json_str = r#"{"name": "Alice", "age": 30, "active": true}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("name:"));
assert!(toon_content.contains("Alice"));
assert!(toon_content.contains("age:"));
assert!(toon_content.contains("30"));
assert!(toon_content.contains("active:"));
assert!(toon_content.contains("true"));
assert!(!toon_content.contains("{"));
assert!(!toon_content.contains("}"));
assert!(!toon_content.contains(":"));
assert!(!toon_content.contains("\""));
}
#[test]
fn test_array_conversion() {
let config = ConversionConfig::default();
let json_str = r#"[1, 2, 3, 4, 5]"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.starts_with("[5]:"));
assert!(toon_content.contains("1,2,3,4,5"));
assert!(!toon_content.contains("["));
assert!(!toon_content.contains("]"));
}
#[test]
fn test_user_array_conversion() {
let config = ConversionConfig::default();
let json_str = r#"[{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("[2,]{id,name}:"));
assert!(toon_content.contains("1,Alice"));
assert!(toon_content.contains("2,Bob"));
assert!(!toon_content.contains("{\"id\":"));
assert!(!toon_content.contains("\"name\":"));
}
#[test]
fn test_nested_object_conversion() {
let config = ConversionConfig::default();
let json_str = r#"{"user": {"name": "Alice", "settings": {"theme": "dark"}}}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("user:"));
assert!(toon_content.contains("name:"));
assert!(toon_content.contains("Alice"));
assert!(toon_content.contains("settings:"));
assert!(toon_content.contains("theme:"));
assert!(toon_content.contains("dark"));
let lines: Vec<&str> = toon_content.lines().collect();
assert!(lines.len() >= 3); }
#[test]
fn test_empty_object() {
let config = ConversionConfig::default();
let json_str = r#"{}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert_eq!(toon_content.trim(), "{}");
}
#[test]
fn test_empty_array() {
let config = ConversionConfig::default();
let json_str = r#"[]"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert_eq!(toon_content.trim(), "[]");
}
#[test]
fn test_null_values() {
let config = ConversionConfig::default();
let json_str = r#"{"value": null}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("value:"));
assert!(toon_content.contains("null"));
}
#[test]
fn test_number_types() {
let config = ConversionConfig::default();
let json_str = r#"{"integer": 42, "float": 3.14, "negative": -10}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("integer:"));
assert!(toon_content.contains("42"));
assert!(toon_content.contains("float:"));
assert!(toon_content.contains("3.14"));
assert!(toon_content.contains("negative:"));
assert!(toon_content.contains("-10"));
}
#[test]
fn test_boolean_values() {
let config = ConversionConfig::default();
let json_str = r#"{"active": true, "inactive": false}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("active:"));
assert!(toon_content.contains("true"));
assert!(toon_content.contains("inactive:"));
assert!(toon_content.contains("false"));
}
#[test]
fn test_invalid_json_syntax() {
let config = ConversionConfig::default();
let invalid_json = r#"{"name": "test", "value": }"#;
let result = convert_json_string(invalid_json, &config);
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("JSON parse error"));
}
#[test]
fn test_unterminated_json_string() {
let config = ConversionConfig::default();
let invalid_json = r#"{"name": "test"#;
let result = convert_json_string(invalid_json, &config);
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("JSON parse error"));
}
#[test]
fn test_empty_input_string() {
let config = ConversionConfig::default();
let empty_json = "";
let result = convert_json_string(empty_json, &config);
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("Empty JSON string"));
}
#[test]
fn test_whitespace_only_string() {
let config = ConversionConfig::default();
let whitespace_json = " \n\t ";
let result = convert_json_string(whitespace_json, &config);
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("Empty JSON string"));
}
#[test]
fn test_string_quoting_rules() {
let config = ConversionConfig::default();
let json_str = r#"{"empty": "", "keyword": "true", "number": "42", "normal": "hello"}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("empty: \"\""));
assert!(toon_content.contains("keyword: \"true\""));
assert!(toon_content.contains("number: \"42\""));
assert!(toon_content.contains("normal: hello"));
}
#[test]
fn test_performance_requirement() {
use std::time::Instant;
let config = ConversionConfig::default();
let mut json_parts = Vec::new();
for i in 0..10000 {
json_parts.push(format!(r#"{{"id": {}, "name": "user{}", "active": true}}"#, i, i));
}
let large_json = format!("[{}]", json_parts.join(","));
assert!(large_json.len() < 1_000_000);
let start_time = Instant::now();
let result = convert_json_string(&large_json, &config);
let elapsed = start_time.elapsed();
assert!(result.is_ok(), "Conversion should succeed");
assert!(elapsed.as_secs_f32() < 1.0,
"Conversion should complete in under 1 second, took {:?}", elapsed);
let toon_data = result.unwrap();
assert!(!toon_data.content.is_empty());
}
#[test]
fn test_conversion_metadata() {
let config = ConversionConfig::default();
let json_str = r#"{"name": "Alice", "age": 30}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
assert!(toon_data.metadata.input_size > 0);
assert!(toon_data.metadata.output_size > 0);
assert!(toon_data.metadata.processing_time_ms > 0);
assert!(toon_data.metadata.token_reduction >= 0.0);
assert!(toon_data.metadata.token_reduction > 0.0);
}
#[test]
fn test_custom_configuration() {
let mut config = ConversionConfig::default();
config.indent_size = 4;
config.delimiter = crate::conversion::DelimiterType::Tab;
config.length_marker = true;
let json_str = r#"[{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains('\t'));
assert!(toon_content.contains("[2"));
}
#[test]
fn test_complex_mixed_data() {
let config = ConversionConfig::default();
let json_str = r#"{
"metadata": {
"version": 1,
"author": "system"
},
"users": [
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
],
"tags": ["urgent", "pending"],
"config": {
"timeout": 30,
"retries": 3
}
}"#;
let result = convert_json_string(json_str, &config);
assert!(result.is_ok());
let toon_data = result.unwrap();
let toon_content = toon_data.content;
assert!(toon_content.contains("metadata:"));
assert!(toon_content.contains("version:"));
assert!(toon_content.contains("1"));
assert!(toon_content.contains("[2,]{id,name}:"));
assert!(toon_content.contains("1,Alice"));
assert!(toon_content.contains("2,Bob"));
assert!(toon_content.contains("tags"));
assert!(toon_content.contains("urgent,pending"));
assert!(toon_content.contains("config:"));
assert!(toon_content.contains("timeout:"));
assert!(toon_content.contains("30"));
}
}