use recoco::base::value::{BasicValue, Value};
use recoco::ops::interface::{FlowInstanceContext, SimpleFunctionFactory};
use recoco::setup::AuthRegistry;
use std::sync::Arc;
use thread_flow::functions::parse::ThreadParseFactory;
fn create_mock_context() -> Arc<FlowInstanceContext> {
Arc::new(FlowInstanceContext {
flow_instance_name: "test_flow".to_string(),
auth_registry: Arc::new(AuthRegistry::new()),
})
}
fn empty_spec() -> serde_json::Value {
serde_json::json!({})
}
async fn execute_parse(
content: &str,
language: &str,
file_path: &str,
) -> Result<Value, recoco::prelude::Error> {
let factory = Arc::new(ThreadParseFactory);
let context = create_mock_context();
let build_output = factory.build(empty_spec(), vec![], context).await?;
let executor = build_output.executor.await?;
let inputs = vec![
Value::Basic(BasicValue::Str(content.to_string().into())),
Value::Basic(BasicValue::Str(language.to_string().into())),
Value::Basic(BasicValue::Str(file_path.to_string().into())),
];
executor.evaluate(inputs).await
}
#[tokio::test]
async fn test_error_invalid_syntax_rust() {
let invalid_rust = "fn invalid { this is not valid rust syntax )))";
let result = execute_parse(invalid_rust, "rs", "invalid.rs").await;
assert!(
result.is_ok(),
"Parser should handle invalid syntax gracefully"
);
}
#[tokio::test]
async fn test_error_invalid_syntax_python() {
let invalid_python = "def broken(: invalid syntax here)))\n\tindent error";
let result = execute_parse(invalid_python, "py", "invalid.py").await;
assert!(result.is_ok(), "Parser should handle invalid Python syntax");
}
#[tokio::test]
async fn test_error_invalid_syntax_typescript() {
let invalid_ts = "function broken({ incomplete destructuring";
let result = execute_parse(invalid_ts, "ts", "invalid.ts").await;
assert!(
result.is_ok(),
"Parser should handle invalid TypeScript syntax"
);
}
#[tokio::test]
async fn test_error_unsupported_language() {
let content = "some code here";
let result = execute_parse(content, "unsupported_lang", "test.unsupported").await;
assert!(result.is_err(), "Should error on unsupported language");
if let Err(e) = result {
let error_msg = e.to_string();
assert!(
error_msg.contains("Unsupported language") || error_msg.contains("client"),
"Error should indicate unsupported language, got: {}",
error_msg
);
}
}
#[tokio::test]
async fn test_error_empty_language_string() {
let content = "fn main() {}";
let result = execute_parse(content, "", "test.rs").await;
assert!(result.is_err(), "Should error on empty language string");
}
#[tokio::test]
async fn test_error_whitespace_only_language() {
let content = "fn main() {}";
let result = execute_parse(content, " ", "test.rs").await;
assert!(result.is_err(), "Should error on whitespace-only language");
}
#[tokio::test]
async fn test_large_file_handling() {
let mut large_code = String::new();
for i in 0..2_000 {
large_code.push_str(&format!("fn function_{}() {{ println!(\"test\"); }}\n", i));
}
assert!(large_code.len() > 50_000, "Test file should be >50KB");
let result = execute_parse(&large_code, "rs", "large.rs").await;
assert!(result.is_ok(), "Should handle large files gracefully");
}
#[tokio::test]
async fn test_deeply_nested_code() {
let mut nested_code = String::from("fn main() {\n");
for _ in 0..100 {
nested_code.push_str(" if true {\n");
}
nested_code.push_str(" println!(\"deep\");\n");
for _ in 0..100 {
nested_code.push_str(" }\n");
}
nested_code.push_str("}\n");
let result = execute_parse(&nested_code, "rs", "nested.rs").await;
assert!(result.is_ok(), "Should handle deeply nested code");
}
#[tokio::test]
async fn test_extremely_long_line() {
let long_line = format!("let x = \"{}\";\n", "a".repeat(100_000));
let result = execute_parse(&long_line, "rs", "longline.rs").await;
assert!(result.is_ok(), "Should handle extremely long lines");
}
#[tokio::test]
async fn test_unicode_identifiers() {
let unicode_code = r#"
fn 测试函数() {
let 变量 = 42;
println!("{}", 变量);
}
"#;
let result = execute_parse(unicode_code, "rs", "unicode.rs").await;
assert!(result.is_ok(), "Should handle Unicode identifiers");
}
#[tokio::test]
async fn test_unicode_strings() {
let unicode_strings = r#"
fn main() {
let emoji = "🦀 Rust";
let chinese = "你好世界";
let arabic = "مرحبا بالعالم";
let hindi = "नमस्ते दुनिया";
println!("{} {} {} {}", emoji, chinese, arabic, hindi);
}
"#;
let result = execute_parse(unicode_strings, "rs", "strings.rs").await;
assert!(result.is_ok(), "Should handle Unicode strings");
}
#[tokio::test]
async fn test_mixed_bidirectional_text() {
let bidi_code = r#"
fn main() {
let mixed = "English مع العربية with हिंदी";
println!("{}", mixed);
}
"#;
let result = execute_parse(bidi_code, "rs", "bidi.rs").await;
assert!(result.is_ok(), "Should handle bidirectional text");
}
#[tokio::test]
async fn test_zero_width_characters() {
let zero_width = "fn main() { let x\u{200B} = 42; }\n";
let result = execute_parse(zero_width, "rs", "zerowidth.rs").await;
assert!(result.is_ok(), "Should handle zero-width characters");
}
#[tokio::test]
async fn test_empty_content() {
let result = execute_parse("", "rs", "empty.rs").await;
assert!(result.is_ok(), "Should handle empty content");
if let Ok(Value::Struct(fields)) = result {
assert_eq!(fields.fields.len(), 4, "Should have 4 fields");
}
}
#[tokio::test]
async fn test_whitespace_only_content() {
let whitespace = " \n\t\n \n";
let result = execute_parse(whitespace, "rs", "whitespace.rs").await;
assert!(result.is_ok(), "Should handle whitespace-only content");
}
#[tokio::test]
async fn test_comments_only_content() {
let comments = r#"
// This file contains only comments
/* Multi-line comment
* with no actual code
*/
// Another comment
"#;
let result = execute_parse(comments, "rs", "comments.rs").await;
assert!(result.is_ok(), "Should handle comments-only files");
}
#[tokio::test]
async fn test_missing_content_parameter() {
let factory = Arc::new(ThreadParseFactory);
let context = create_mock_context();
let build_output = factory
.build(empty_spec(), vec![], context)
.await
.expect("Build should succeed");
let executor = build_output.executor.await.expect("Executor should build");
let result = executor.evaluate(vec![]).await;
assert!(result.is_err(), "Should error on missing content");
if let Err(e) = result {
assert!(
e.to_string().contains("Missing content"),
"Error should mention missing content"
);
}
}
#[tokio::test]
async fn test_concurrent_parse_operations() {
use tokio::task::JoinSet;
let mut join_set = JoinSet::new();
for i in 0..10 {
join_set.spawn(async move {
let content = format!("fn function_{}() {{ println!(\"test\"); }}", i);
execute_parse(&content, "rs", &format!("concurrent_{}.rs", i)).await
});
}
let mut successes = 0;
while let Some(result) = join_set.join_next().await {
if let Ok(Ok(_)) = result {
successes += 1;
}
}
assert_eq!(successes, 10, "All concurrent operations should succeed");
}
#[tokio::test]
async fn test_concurrent_same_content() {
use tokio::task::JoinSet;
let content = "fn shared() { println!(\"shared\"); }";
let mut join_set = JoinSet::new();
for i in 0..5 {
let content = content.to_string();
join_set
.spawn(async move { execute_parse(&content, "rs", &format!("shared_{}.rs", i)).await });
}
let mut successes = 0;
while let Some(result) = join_set.join_next().await {
if let Ok(Ok(_)) = result {
successes += 1;
}
}
assert_eq!(successes, 5, "All concurrent parses should succeed");
}
#[tokio::test]
async fn test_null_bytes_in_content() {
let null_content = "fn main() {\0 let x = 42; }";
let result = execute_parse(null_content, "rs", "null.rs").await;
assert!(result.is_ok(), "Should handle null bytes in content");
}
#[tokio::test]
async fn test_only_special_characters() {
let special = "!@#$%^&*()_+-=[]{}|;':\",./<>?";
let result = execute_parse(special, "rs", "special.rs").await;
assert!(
result.is_ok(),
"Should handle special characters gracefully"
);
}
#[tokio::test]
async fn test_repetitive_content() {
let repetitive = "fn a() {}\n".repeat(1000);
let result = execute_parse(&repetitive, "rs", "repetitive.rs").await;
assert!(result.is_ok(), "Should handle repetitive content");
}
#[tokio::test]
async fn test_mixed_line_endings() {
let mixed = "fn main() {\r\n let x = 1;\n let y = 2;\r let z = 3;\r\n}";
let result = execute_parse(mixed, "rs", "mixed.rs").await;
assert!(result.is_ok(), "Should handle mixed line endings");
}
#[tokio::test]
async fn test_invalid_content_type() {
let factory = Arc::new(ThreadParseFactory);
let context = create_mock_context();
let build_output = factory
.build(empty_spec(), vec![], context)
.await
.expect("Build should succeed");
let executor = build_output.executor.await.expect("Executor should build");
let inputs = vec![
Value::Basic(BasicValue::Int64(42)),
Value::Basic(BasicValue::Str("rs".to_string().into())),
Value::Basic(BasicValue::Str("test.rs".to_string().into())),
];
let result = executor.evaluate(inputs).await;
assert!(result.is_err(), "Should error on invalid content type");
}
#[tokio::test]
async fn test_invalid_language_type() {
let factory = Arc::new(ThreadParseFactory);
let context = create_mock_context();
let build_output = factory
.build(empty_spec(), vec![], context)
.await
.expect("Build should succeed");
let executor = build_output.executor.await.expect("Executor should build");
let inputs = vec![
Value::Basic(BasicValue::Str("content".to_string().into())),
Value::Basic(BasicValue::Int64(42)),
Value::Basic(BasicValue::Str("test.rs".to_string().into())),
];
let result = executor.evaluate(inputs).await;
assert!(result.is_err(), "Should error on invalid language type");
}
#[tokio::test]
async fn test_rapid_sequential_parsing() {
const ITERATIONS: usize = 20;
for i in 0..ITERATIONS {
let content = format!("fn func_{}() {{ println!(\"test\"); }}", i);
let result = execute_parse(&content, "rs", &format!("rapid_{}.rs", i)).await;
assert!(result.is_ok(), "Iteration {} should succeed", i);
}
println!("✓ Completed {} rapid sequential parses", ITERATIONS);
}
#[tokio::test]
async fn test_varied_file_sizes() {
let sizes = vec![10, 100, 1000, 10000];
for size in sizes {
let mut content = String::new();
for i in 0..size {
content.push_str(&format!("fn f_{}() {{}}\n", i));
}
let result = execute_parse(&content, "rs", &format!("size_{}.rs", size)).await;
assert!(result.is_ok(), "File with {} functions should parse", size);
}
}