use std::fs::File; use pest::Parser; use json_parser_with_pest::parser::{JSONParser, Rule}; use anyhow::{Context, Result}; use serde_json::{json, Value}; use tempfile::tempdir; #[cfg(test)] mod tests { use super::*; use serde_json::{json, Value}; use std::fs::File; use std::io::Write; use pest::Parser; use tempfile::tempdir; /// Tests basic JSON parsing functionality. #[test] fn test_parse_simple_json() -> Result<()> { let json_data = r#"{ "name": "John", "age": 30, "city": "New York" }"#; let result = json_parser_with_pest::parse_json(json_data) .context("Failed to parse valid JSON")?; assert!(result.is_object(), "Expected parsed JSON to be an object."); Ok(()) } /// Tests JSON schema validation functionality. #[test] fn test_validate_json_schema() -> Result<()> { let json_data = json!({ "name": "John", "age": 30 }); let schema = json!({ "name": "", "age": 0 }); json_parser_with_pest::validate_json_schema(&json_data, &schema) .context("Schema validation failed for valid JSON and schema")?; Ok(()) } /// Tests partial JSON parsing by a specific key. #[test] fn test_parse_partial_json() -> Result<()> { let json_data = json!({ "name": "John", "age": 30, "city": "New York" }); let result = json_parser_with_pest::parse_partial_json(&json_data, "city") .context("Failed to retrieve value for the key 'city'")?; assert_eq!(result, json!("New York"), "Incorrect value retrieved for 'city'."); Ok(()) } /// Tests editing a JSON object by modifying a specific key's value. #[test] fn test_edit_json() -> Result<()> { let mut json_data = json!({ "name": "John", "age": 30 }); json_parser_with_pest::edit_json(&mut json_data, "age", json!(35)) .context("Failed to edit JSON key 'age'")?; assert_eq!( json_data["age"], 35, "Value of key 'age' did not update correctly." ); Ok(()) } /// Tests conversion of JSON to YAML format. #[test] fn test_convert_to_yaml() -> Result<()> { let json_data = json!({ "name": "John", "age": 30 }); let result = json_parser_with_pest::convert_to_format(&json_data, "yaml") .context("Failed to convert JSON to YAML")?; assert!( result.contains("name: John"), "YAML conversion did not contain expected data." ); Ok(()) } /// Tests conversion of JSON to XML format. #[test] fn test_convert_to_xml() -> Result<()> { let json_data = json!({ "name": "John", "age": 30 }); let result = json_parser_with_pest::convert_to_format(&json_data, "xml") .context("Failed to convert JSON to XML")?; assert!( result.contains("John"), "XML conversion did not contain expected data." ); Ok(()) } /// Tests handling of large JSON files by parsing them in chunks. #[test] fn test_handle_large_json() -> Result<()> { let dir = tempdir().context("Failed to create temporary directory")?; let file_path = dir.path().join("large_test.json"); let mut file = File::create(&file_path).context("Failed to create temporary file")?; write!( file, "[{}]", (0..1000) .map(|_| "{\"key\": \"value\"}") .collect::>() .join(",") ) .context("Failed to write large JSON data to temporary file")?; json_parser_with_pest::handle_large_json(&file_path) .context("Failed to handle large JSON file")?; Ok(()) } /// Tests minifying JSON by removing whitespace. #[test] fn test_minify_json() -> Result<()> { let json_data = json!({ "name": "John", "age": 30, "city": "New York" }); let minified = json_parser_with_pest::parser::minify_json(&json_data); let parsed_minified: Value = serde_json::from_str(&minified).context("Failed to parse minified JSON")?; assert_eq!( parsed_minified, json_data, "Minified JSON does not match the original structure." ); Ok(()) } /// Tests retrieving a value by JSON path. #[test] fn test_get_by_path() -> Result<()> { let json_data = json!({ "data": { "items": [ { "name": "Item1" }, { "name": "Item2" } ] } }); let result = json_parser_with_pest::parser::get_by_path(&json_data, "data.items[1].name") .context("Failed to retrieve value by JSON path")?; assert_eq!(result, json!("Item2"), "Incorrect value retrieved by JSON path."); Ok(()) } /// Tests searching JSON by a specific value, retrieving paths where the value is found. #[test] fn test_search_by_value() -> Result<()> { let json_data = json!({ "name": "John", "details": { "age": 30, "location": "New York", "nickname": "John" } }); let mut results = json_parser_with_pest::parser::search_by_value(&json_data, "John"); results.sort(); assert_eq!( results, vec!["details.nickname", "name"], "Failed to find correct paths for value 'John'." ); Ok(()) } /// Tests invalid JSON input parsing. #[test] fn test_invalid_json_parse() -> Result<()> { let invalid_json_data = "{ name: John, age: 30 }"; // Invalid JSON let result = json_parser_with_pest::parse_json(invalid_json_data); assert!( result.is_err(), "Expected failure for invalid JSON input, but parsing succeeded." ); Ok(()) } /// Tests recursive JSON object parsing. #[test] fn test_recursive_object_parsing() -> Result<()> { let input = r#" { "key1": { "nested_key": { "deep_nested_key": "value" } } } "#; JSONParser::parse(Rule::json, input).context("Failed to parse nested JSON object")?; Ok(()) } /// Tests edge cases for empty objects and arrays. #[test] fn test_empty_structures() -> Result<()> { let valid_inputs = vec!["{}", "[]"]; for input in valid_inputs { JSONParser::parse(Rule::json, input) .with_context(|| format!("Failed to parse empty structure: {}", input))?; } Ok(()) } } /// Tests basic JSON parsing functionality. #[test] fn test_parse_simple_json() { let json_data = r#"{ "name": "John", "age": 30, "city": "New York" }"#; let result = json_parser_with_pest::parse_json(json_data); assert!( result.is_ok(), "Failed to parse valid JSON: {:?}", result.err() ); } /// Tests JSON schema validation functionality. #[test] fn test_validate_json_schema() { let json_data = json!({ "name": "John", "age": 30 }); let schema = json!({ "name": "", "age": 0 }); let result = json_parser_with_pest::validate_json_schema(&json_data, &schema); assert!( result.is_ok(), "Schema validation failed for valid JSON and schema." ); } /// Tests partial JSON parsing by a specific key. #[test] fn test_parse_partial_json() { let json_data = json!({ "name": "John", "age": 30, "city": "New York" }); let result = json_parser_with_pest::parse_partial_json(&json_data, "city"); assert_eq!( result, Some(json!("New York")), "Failed to retrieve the correct value for the key 'city'." ); } /// Tests editing a JSON object by modifying a specific key's value. #[test] fn test_edit_json() { let mut json_data = json!({ "name": "John", "age": 30 }); let result = json_parser_with_pest::edit_json(&mut json_data, "age", json!(35)); assert!(result.is_ok(), "Failed to edit JSON key 'age'."); assert_eq!( json_data["age"], 35, "Value of key 'age' did not update correctly." ); } /// Tests conversion of JSON to YAML format. #[test] fn test_convert_to_yaml() { let json_data = json!({ "name": "John", "age": 30 }); let result = json_parser_with_pest::convert_to_format(&json_data, "yaml"); assert!( result.is_ok(), "Failed to convert JSON to YAML: {:?}", result.err() ); assert!( result.unwrap().contains("name: John"), "YAML conversion did not contain expected data." ); } /// Tests conversion of JSON to XML format. #[test] fn test_convert_to_xml() { let json_data = json!({ "name": "John", "age": 30 }); let result = json_parser_with_pest::convert_to_format(&json_data, "xml"); assert!( result.is_ok(), "Failed to convert JSON to XML: {:?}", result.err() ); assert!( result.unwrap().contains("John"), "XML conversion did not contain expected data." ); } /// Tests handling of large JSON files by parsing them in chunks. #[test] fn test_handle_large_json() { use std::io::Write; // Імпорт для запису у файл // Створення тимчасового каталогу let dir = tempdir().expect("Failed to create temp directory"); let file_path = dir.path().join("large_test.json"); // Створення тимчасового файлу let mut file = File::create(&file_path).expect("Failed to create temp file"); // Запис великих даних у файл let json_content = format!( "[{}]", (0..1000) .map(|_| "{\"key\": \"value\"}") .collect::>() .join(",") ); file.write_all(json_content.as_bytes()) .expect("Failed to write to file"); // Тестування функції handle_large_json let result = json_parser_with_pest::handle_large_json(&file_path); assert!( result.is_ok(), "Failed to handle large JSON file: {:?}", result.err() ); } /// Tests minifying JSON by removing whitespace. #[test] fn test_minify_json() { let json_data = json!({ "name": "John", "age": 30, "city": "New York" }); let minified = json_parser_with_pest::parser::minify_json(&json_data); let parsed_minified: Value = serde_json::from_str(&minified).unwrap(); assert_eq!( parsed_minified, json_data, "Minified JSON does not match the original structure." ); } /// Tests retrieving a value by JSON path. #[test] fn test_get_by_path() { let json_data = json!({ "data": { "items": [ { "name": "Item1" }, { "name": "Item2" } ] } }); let result = json_parser_with_pest::parser::get_by_path(&json_data, "data.items[1].name"); assert_eq!( result, Some(json!("Item2")), "Failed to retrieve value by JSON path." ); } /// Tests searching JSON by a specific value, retrieving paths where the value is found. #[test] fn test_search_by_value() { let json_data = json!({ "name": "John", "details": { "age": 30, "location": "New York", "nickname": "John" } }); let mut results = json_parser_with_pest::parser::search_by_value(&json_data, "John"); results.sort(); assert_eq!( results, vec!["details.nickname", "name"], "Failed to find correct paths for value 'John'." ); } /// Tests handling of invalid JSON input. /// Tests handling of invalid JSON input. #[test] fn test_invalid_json_parse() { let invalid_json_data = "{ name: John, age: 30 }"; // Invalid JSON due to missing quotes let result = json_parser_with_pest::parse_json(invalid_json_data); // Перевіряємо, чи повертається помилка assert!( result.is_err(), "Expected failure for invalid JSON input, but parsing succeeded." ); // Перевіряємо, чи повернена помилка є саме ParsingError if let Err(err) = result { assert!( matches!(err, json_parser_with_pest::ParserError::JsonParseError), "Expected JsonParseError, but got: {:?}", err ); } } /// Tests validation of JSON schema with extra keys in the schema. #[test] fn test_invalid_json_schema() { let json_data = json!({ "name": "John", "age": 30 }); let schema = json!({ "name": "", "age": 0, "extra_key": "" }); /* // Якщо дозволяємо надлишкові ключі в схемі let result = json_parser_with_pest::validate_json_schema(&json_data, &schema); assert!( result.is_ok(), "Expected schema validation to succeed, but it failed: {:?}", result.err() ); */ // Якщо надлишкові ключі мають викликати помилку let result = json_parser_with_pest::validate_json_schema(&json_data, &schema); assert!( result.is_err(), "Expected schema validation to fail due to extra key in schema." ); } /// Tests parsing invalid key-value arrays. #[test] fn test_key_value_array_invalid() { let inputs = vec![ r#" [ { "key1": "value1" }, { "key2" "value2" } // Missing colon ] "#, r#" [ { "key1": "value1" }, "not_an_object" ] "#, r#" [ { "key1": "value1", "key2": "value2" } "# // Missing closing bracket ]; for input in inputs { let result = JSONParser::parse(Rule::key_value_array, input); assert!( result.is_err(), "Expected failure for invalid key-value array: {}. Result: {:?}", input, result ); } } /// Test parsing of JSON date in format YYYY-MM-DD. #[test] fn test_date_parsing() { let valid_dates = vec!["2023-11-15", "2000-01-01", "1999-12-31"]; for date in valid_dates { let result = JSONParser::parse(Rule::date, date); assert!( result.is_ok(), "Failed to parse valid date: {}. Error: {:?}", date, result.err() ); } let invalid_dates = vec!["2023-13-01", "202-11-15", "2023-11", "abcd-11-15"]; for date in invalid_dates { let result = JSONParser::parse(Rule::date, date); assert!( result.is_err(), "Parsed invalid date: {}. Result: {:?}", date, result ); } } /// Test parsing of JSON identifier. #[test] fn test_identifier_parsing() { let valid_identifiers = vec!["key", "key1", "_key", "key_name", "Key123"]; for identifier in valid_identifiers { let result = JSONParser::parse(Rule::identifier, identifier); assert!( result.is_ok(), "Failed to parse valid identifier: {}. Error: {:?}", identifier, result.err() ); } let invalid_identifiers = vec!["1key", "-key", "key@", "key name"]; for identifier in invalid_identifiers { let result = JSONParser::parse(Rule::identifier, identifier); assert!( result.is_err(), "Parsed invalid identifier: {}. Result: {:?}", identifier, result ); } } /// Test parsing of SemVer version strings. #[test] fn test_version_parsing() { let valid_versions = vec![ "1.0.0", "2.1.3-alpha", "3.2.1-beta.1", "4.5.6+build.123", "0.1.0", "10.20.30-pre.4+metadata.12345", ]; for version in valid_versions { let result = JSONParser::parse(Rule::version, version); assert!( result.is_ok(), "Failed to parse valid version: {}. Error: {:?}", version, result.err() ); } let invalid_versions = vec![ "1.0", "v1.0.0", "1.0.0-", "1.0.0+", "1.0.0-beta..1", "1.0.0-alpha+build@123", ]; for version in invalid_versions { let result = JSONParser::parse(Rule::version, version); assert!( result.is_err(), "Parsed invalid version: {}. Result: {:?}", version, result ); } } /// Test parsing of key-value arrays. #[test] fn test_key_value_array_parsing() { let valid_arrays = vec![ r#"[{ "key1": "value1" }, { "key2": "value2" }]"#, r#"[{ "key": "value" }]"#, r#"[]"#, ]; for array in valid_arrays { let result = JSONParser::parse(Rule::key_value_array, array); assert!( result.is_ok(), "Failed to parse valid key-value array: {}. Error: {:?}", array, result.err() ); } let invalid_arrays = vec![ r#"[{ "key1": "value1" }, { "key2" "value2" }]"#, // Missing colon r#"[{ "key": "value" }, "string"]"#, // Non-object element r#"[{ "key": "value""#, // Missing closing bracket ]; for array in invalid_arrays { let result = JSONParser::parse(Rule::key_value_array, array); assert!( result.is_err(), "Parsed invalid key-value array: {}. Result: {:?}", array, result ); } } /// Test recursive JSON object parsing. #[test] fn test_recursive_object_parsing() { let input = r#" { "key1": { "nested_key": { "deep_nested_key": "value" } } } "#; let result = JSONParser::parse(Rule::json, input); assert!( result.is_ok(), "Failed to parse nested JSON object. Error: {:?}", result.err() ); } /// Test parsing of JSON arrays with mixed types. #[test] fn test_mixed_type_array_parsing() { let input = r#"[123, "string", true, null, { "key": "value" }, [1, 2, 3]]"#; let result = JSONParser::parse(Rule::json, input); assert!( result.is_ok(), "Failed to parse mixed-type array. Error: {:?}", result.err() ); } /// Test edge cases for empty objects and arrays. #[test] fn test_empty_structures() { let valid_inputs = vec!["{}", "[]"]; for input in valid_inputs { let result = JSONParser::parse(Rule::json, input); assert!( result.is_ok(), "Failed to parse empty structure: {}. Error: {:?}", input, result.err() ); } }