@@ -2319,4 +2319,119 @@ mod tests {
23192319 // Should correctly parse the AND chain inside parentheses
23202320 assert ! ( where_clause. conditions. len( ) > 0 ) ;
23212321 }
2322+
2323+ // Format preservation tests - ensure F3 multi-line mode preserves parentheses
2324+ #[ test]
2325+ fn test_format_preserves_simple_parentheses ( ) {
2326+ let query = r#"SELECT * FROM trades WHERE (status = "active" OR status = "pending")"# ;
2327+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2328+ let formatted_text = formatted. join ( " " ) ;
2329+
2330+ // Check parentheses are preserved
2331+ assert ! ( formatted_text. contains( "(status" ) ) ;
2332+ assert ! ( formatted_text. contains( "\" pending\" )" ) ) ;
2333+
2334+ // Count parentheses
2335+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2336+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2337+ assert_eq ! ( original_parens, formatted_parens, "Parentheses should be preserved" ) ;
2338+ }
2339+
2340+ #[ test]
2341+ fn test_format_preserves_complex_parentheses ( ) {
2342+ let query = r#"SELECT * FROM trades WHERE (symbol = "AAPL" OR symbol = "GOOGL") AND price > 100"# ;
2343+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2344+ let formatted_text = formatted. join ( " " ) ;
2345+
2346+ // Check the grouped OR condition is preserved
2347+ assert ! ( formatted_text. contains( "(symbol" ) ) ;
2348+ assert ! ( formatted_text. contains( "\" GOOGL\" )" ) ) ;
2349+
2350+ // Verify parentheses count
2351+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2352+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2353+ assert_eq ! ( original_parens, formatted_parens) ;
2354+ }
2355+
2356+ #[ test]
2357+ fn test_format_preserves_nested_parentheses ( ) {
2358+ let query = r#"SELECT * FROM trades WHERE ((symbol = "AAPL" OR symbol = "GOOGL") AND price > 100) OR status = "cancelled""# ;
2359+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2360+ let formatted_text = formatted. join ( " " ) ;
2361+
2362+ // Count nested parentheses
2363+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2364+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2365+ assert_eq ! ( original_parens, formatted_parens, "Nested parentheses should be preserved" ) ;
2366+ assert_eq ! ( original_parens, 4 , "Should have 4 parentheses total" ) ;
2367+ }
2368+
2369+ #[ test]
2370+ fn test_format_preserves_method_calls_in_parentheses ( ) {
2371+ let query = r#"SELECT * FROM trades WHERE (symbol.StartsWith("A") OR symbol.StartsWith("G")) AND volume > 1000000"# ;
2372+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2373+ let formatted_text = formatted. join ( " " ) ;
2374+
2375+ // Check method calls are preserved with their parentheses
2376+ assert ! ( formatted_text. contains( "(symbol.StartsWith" ) ) ;
2377+ assert ! ( formatted_text. contains( "StartsWith(\" A\" )" ) ) ;
2378+ assert ! ( formatted_text. contains( "StartsWith(\" G\" )" ) ) ;
2379+
2380+ // Count all parentheses (including method calls)
2381+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2382+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2383+ assert_eq ! ( original_parens, formatted_parens) ;
2384+ assert_eq ! ( original_parens, 6 , "Should have 6 parentheses (1 group + 2 method calls)" ) ;
2385+ }
2386+
2387+ #[ test]
2388+ fn test_format_preserves_multiple_groups ( ) {
2389+ let query = r#"SELECT * FROM trades WHERE (symbol = "AAPL" OR symbol = "GOOGL") AND (price > 100 AND price < 500)"# ;
2390+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2391+ let formatted_text = formatted. join ( " " ) ;
2392+
2393+ // Both groups should be preserved
2394+ assert ! ( formatted_text. contains( "(symbol" ) ) ;
2395+ assert ! ( formatted_text. contains( "(price" ) ) ;
2396+
2397+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2398+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2399+ assert_eq ! ( original_parens, formatted_parens) ;
2400+ assert_eq ! ( original_parens, 4 , "Should have 4 parentheses (2 groups)" ) ;
2401+ }
2402+
2403+ #[ test]
2404+ fn test_format_preserves_date_ranges ( ) {
2405+ let query = r#"SELECT * FROM trades WHERE (executionDate > DateTime(2024, 1, 1) AND executionDate < DateTime(2024, 12, 31))"# ;
2406+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2407+ let formatted_text = formatted. join ( " " ) ;
2408+
2409+ // Check DateTime functions and grouping are preserved
2410+ assert ! ( formatted_text. contains( "(executionDate" ) ) ;
2411+ assert ! ( formatted_text. contains( "DateTime(2024, 1, 1)" ) ) ;
2412+ assert ! ( formatted_text. contains( "DateTime(2024, 12, 31)" ) ) ;
2413+
2414+ let original_parens = query. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2415+ let formatted_parens = formatted_text. chars ( ) . filter ( |c| * c == '(' || * c == ')' ) . count ( ) ;
2416+ assert_eq ! ( original_parens, formatted_parens) ;
2417+ }
2418+
2419+ #[ test]
2420+ fn test_format_multiline_layout ( ) {
2421+ // Test that formatted output has proper multi-line structure
2422+ let query = r#"SELECT * FROM trades WHERE (symbol = "AAPL" OR symbol = "GOOGL") AND price > 100"# ;
2423+ let formatted = format_sql_pretty_compact ( query, 5 ) ;
2424+
2425+ // Should have SELECT, FROM, WHERE, and condition lines
2426+ assert ! ( formatted. len( ) >= 4 , "Should have multiple lines" ) ;
2427+ assert_eq ! ( formatted[ 0 ] , "SELECT" ) ;
2428+ assert ! ( formatted[ 1 ] . trim( ) . starts_with( "*" ) ) ;
2429+ assert ! ( formatted[ 2 ] . starts_with( "FROM" ) ) ;
2430+ assert_eq ! ( formatted[ 3 ] , "WHERE" ) ;
2431+
2432+ // WHERE conditions should be indented
2433+ let where_lines: Vec < _ > = formatted. iter ( ) . skip ( 4 ) . collect ( ) ;
2434+ assert ! ( where_lines. iter( ) . any( |l| l. contains( "(symbol" ) ) ) ;
2435+ assert ! ( where_lines. iter( ) . any( |l| l. trim( ) == "AND" ) ) ;
2436+ }
23222437}
0 commit comments