#[test]
fn test_format_for_loop_simple() {
let result = format_code("for i in 0..10 { println(i) }");
assert!(result.contains("for"));
assert!(result.contains("in"));
}
#[test]
fn test_format_for_loop_with_list() {
let result = format_code("for x in [1, 2, 3] { x }");
assert!(result.contains("for"));
assert!(result.contains("[1, 2, 3]"));
}
#[test]
fn test_format_index_access() {
let result = format_code("arr[0]");
assert!(result.contains("arr[0]") || result.contains("arr") && result.contains("[0]"));
}
#[test]
fn test_format_index_access_expression() {
let result = format_code("arr[i + 1]");
assert!(result.contains("["));
assert!(result.contains("]"));
}
#[test]
fn test_format_assign() {
let result = format_code("x = 42");
assert!(result.contains("x") && result.contains("=") && result.contains("42"));
}
#[test]
fn test_format_assign_expression() {
let result = format_code("x = y + 1");
assert!(result.contains("="));
}
#[test]
fn test_format_return_value() {
let result = format_code("return 42");
assert!(result.contains("return") && result.contains("42"));
}
#[test]
fn test_format_return_empty() {
let result = format_code("return");
assert!(result.contains("return"));
}
#[test]
fn test_format_field_access() {
let result = format_code("obj.field");
assert!(
result.contains("obj.field") || (result.contains("obj") && result.contains("field"))
);
}
#[test]
fn test_format_chained_field_access() {
let result = format_code("a.b.c");
assert!(result.contains("."));
}
#[test]
fn test_format_while_loop() {
let result = format_code("while x < 10 { x = x + 1 }");
assert!(result.contains("while"));
}
#[test]
fn test_format_while_true() {
let result = format_code("while true { break }");
assert!(result.contains("while") && result.contains("true"));
}
#[test]
fn test_format_break() {
let result = format_code("break");
assert_eq!(result.trim(), "break");
}
#[test]
fn test_format_break_with_value() {
let result = format_code("break 42");
assert!(result.contains("break") && result.contains("42"));
}
#[test]
fn test_format_continue() {
let result = format_code("continue");
assert_eq!(result.trim(), "continue");
}
#[test]
fn test_format_range_exclusive() {
let result = format_code("0..10");
assert!(result.contains("0") && result.contains("10") && result.contains(".."));
}
#[test]
fn test_format_range_inclusive() {
let result = format_code("0..=10");
assert!(result.contains("..=") || result.contains(".."));
}
#[test]
fn test_format_unary_negative() {
let result = format_code("-42");
assert!(result.contains("-") && result.contains("42"));
}
#[test]
fn test_format_unary_not() {
let result = format_code("!true");
assert!(result.contains("!") && result.contains("true"));
}
#[test]
fn test_format_empty_list() {
let result = format_code("[]");
assert!(result.contains("[]"));
}
#[test]
fn test_format_list_with_elements() {
let result = format_code("[1, 2, 3]");
assert!(result.contains("[") && result.contains("]"));
assert!(result.contains("1") && result.contains("2") && result.contains("3"));
}
#[test]
fn test_format_tuple() {
let result = format_code("(1, 2, 3)");
assert!(result.contains("(") && result.contains(")"));
}
#[test]
fn test_format_tuple_single() {
let result = format_code("(42,)");
assert!(result.contains("42"));
}
#[test]
fn test_format_match_simple() {
let code = r#"match x {
1 => "one",
_ => "other"
}"#;
let result = format_code(code);
assert!(result.contains("match"));
}
#[test]
fn test_format_compound_assign_add() {
let result = format_code("x += 1");
assert!(result.contains("+=") || (result.contains("+") && result.contains("=")));
}
#[test]
fn test_format_compound_assign_sub() {
let result = format_code("x -= 1");
assert!(result.contains("-=") || result.contains("-"));
}
#[test]
fn test_format_compound_assign_mul() {
let result = format_code("x *= 2");
assert!(result.contains("*=") || result.contains("*"));
}
#[test]
fn test_format_lambda_simple() {
let result = format_code("|x| x + 1");
assert!(result.contains("|"));
}
#[test]
fn test_format_lambda_multiple_params() {
let result = format_code("|x, y| x + y");
assert!(result.contains("|") && result.contains(","));
}
#[test]
fn test_format_empty_object() {
let result = format_code("{}");
assert!(result.contains("{") && result.contains("}"));
}
#[test]
fn test_format_object_with_fields() {
let result = format_code("{ x: 1, y: 2 }");
assert!(result.contains("x") && result.contains("y"));
}
#[test]
fn test_format_ternary() {
let result = format_code("x > 0 ? 1 : -1");
assert!(result.contains("?") && result.contains(":"));
}
#[test]
fn test_format_try_catch() {
let result = try_format("try { risky() } catch (e) { handle(e) }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_throw() {
let result = format_code("throw Error(\"oops\")");
assert!(result.contains("throw"));
}
#[test]
fn test_format_await() {
let result = format_code("await fetch(url)");
assert!(result.contains("await"));
}
#[test]
fn test_format_async_block() {
let result = format_code("async { 42 }");
assert!(result.contains("async"));
}
#[test]
fn test_format_type_cast() {
let result = format_code("x as Int");
assert!(result.contains("as"));
}
#[test]
fn test_format_array_init() {
let result = format_code("[0; 10]");
assert!(result.contains("[") && result.contains(";") && result.contains("]"));
}
#[test]
fn test_format_some() {
let result = format_code("Some(42)");
assert!(result.contains("Some") && result.contains("42"));
}
#[test]
fn test_format_none() {
let result = format_code("None");
assert!(result.contains("None"));
}
#[test]
fn test_format_ok() {
let result = format_code("Ok(42)");
assert!(result.contains("Ok") && result.contains("42"));
}
#[test]
fn test_format_err() {
let result = format_code("Err(\"error\")");
assert!(result.contains("Err"));
}
#[test]
fn test_format_try_operator() {
let result = format_code("result?");
assert!(result.contains("?"));
}
#[test]
fn test_format_spawn() {
let result = format_code("spawn MyActor {}");
assert!(result.contains("spawn") || result.contains("MyActor"));
}
#[test]
fn test_format_if_let() {
let result = format_code("if let Some(x) = opt { x }");
assert!(result.contains("if") && result.contains("let"));
}
#[test]
fn test_format_if_let_with_else() {
let result = format_code("if let Some(x) = opt { x } else { 0 }");
assert!(result.contains("if") && result.contains("else"));
}
#[test]
fn test_format_optional_field_access() {
let result = format_code("obj?.field");
assert!(result.contains("?.") || (result.contains("?") && result.contains(".")));
}
#[test]
fn test_format_slice_full() {
let result = format_code("arr[1..3]");
assert!(result.contains("[") && result.contains("..") && result.contains("]"));
}
#[test]
fn test_format_method_call() {
let result = format_code("obj.method()");
assert!(result.contains(".method"));
}
#[test]
fn test_format_method_call_with_args() {
let result = format_code("obj.method(1, 2)");
assert!(result.contains(".method") && result.contains("1") && result.contains("2"));
}
#[test]
fn test_format_function_with_return_type() {
let result = format_code("fun add(a: Int, b: Int) -> Int { a + b }");
assert!(result.contains("fun") && result.contains("->"));
}
#[test]
fn test_format_async_function() {
let result = format_code("async fun fetch() { await http_get() }");
assert!(result.contains("async") || result.contains("fun"));
}
#[test]
fn test_format_struct_literal() {
let result = format_code("Point { x: 1, y: 2 }");
assert!(result.contains("Point") && result.contains("x") && result.contains("y"));
}
#[test]
fn test_format_nested_if() {
let result = format_code("if a { if b { 1 } else { 2 } } else { 3 }");
assert!(result.contains("if") && result.contains("else"));
}
#[test]
fn test_format_binary_chain() {
let result = format_code("1 + 2 * 3 - 4");
assert!(result.contains("+") && result.contains("*") && result.contains("-"));
}
#[test]
fn test_format_deeply_nested() {
let result = format_code("{ { { 42 } } }");
assert!(result.contains("{") && result.contains("}") && result.contains("42"));
}
#[test]
fn test_format_empty_function_body() {
let result = format_code("fun empty() { }");
assert!(result.contains("fun") && result.contains("empty"));
}
#[test]
fn test_format_multiline_block() {
let code = r#"{
let x = 1
let y = 2
x + y
}"#;
let result = format_code(code);
assert!(result.contains("let x") && result.contains("let y"));
}
#[test]
fn test_format_large_integer() {
let result = format_code("999999999999");
assert!(result.contains("999999999999"));
}
#[test]
fn test_format_float_scientific() {
let result = format_code("1.5e10");
assert!(!result.is_empty());
}
#[test]
fn test_format_string_empty() {
let result = format_code("\"\"");
assert!(result.contains("\"\""));
}
#[test]
fn test_format_string_with_newline() {
let result = format_code("\"hello\\nworld\"");
assert!(result.contains("hello"));
}
#[test]
fn test_format_struct_declaration() {
let result = format_code("struct Point { x: Int, y: Int }");
assert!(result.contains("struct") && result.contains("Point"));
}
#[test]
fn test_format_pub_struct() {
let result = format_code("pub struct Point { x: Int }");
assert!(result.contains("pub") && result.contains("struct"));
}
#[test]
fn test_format_struct_with_generics() {
let result = format_code("struct Box<T> { value: T }");
assert!(result.contains("Box") && result.contains("<T>"));
}
#[test]
fn test_format_tuple_struct() {
let result = format_code("struct Point(Int, Int)");
assert!(result.contains("struct") && result.contains("Point"));
}
#[test]
fn test_format_pub_tuple_struct() {
let result = format_code("pub struct Wrapper(Int)");
assert!(result.contains("pub") && result.contains("struct"));
}
#[test]
fn test_format_enum_simple() {
let result = format_code("enum Color { Red, Green, Blue }");
assert!(result.contains("enum") && result.contains("Color"));
}
#[test]
fn test_format_pub_enum() {
let result = try_format("pub enum Color { Red, Green }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_trait_simple() {
let result = format_code("trait Display { fun show() -> String }");
assert!(result.contains("trait") && result.contains("Display"));
}
#[test]
fn test_format_pub_trait() {
let result = format_code("pub trait Clone { fun clone() -> Self }");
assert!(result.contains("pub") && result.contains("trait"));
}
#[test]
fn test_format_impl_block() {
let result = format_code("impl Point { fun new() { Point { x: 0, y: 0 } } }");
assert!(result.contains("impl") && result.contains("Point"));
}
#[test]
fn test_format_impl_trait_for_type() {
let result = format_code("impl Display for Point { fun show() { \"point\" } }");
assert!(result.contains("impl") && result.contains("for"));
}
#[test]
fn test_format_module() {
let result = format_code("mod math { fun add(a, b) { a + b } }");
assert!(result.contains("mod") && result.contains("math"));
}
#[test]
fn test_format_module_declaration() {
let result = format_code("mod utils;");
assert!(result.contains("mod") && result.contains("utils"));
}
#[test]
fn test_format_import_module() {
let result = try_format("import std::io");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_import_items() {
let result = try_format("import std::io::{read, write}");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_import_all() {
let result = try_format("import std::io::*");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_export() {
let result = format_code("export fun add(a, b) { a + b }");
assert!(result.contains("export"));
}
#[test]
fn test_format_export_default() {
let result = format_code("export default 42");
assert!(result.contains("export") && result.contains("default"));
}
#[test]
fn test_format_export_list() {
let result = format_code("export { add, sub }");
assert!(result.contains("export") && result.contains("{"));
}
#[test]
fn test_format_let_pattern_tuple() {
let result = format_code("let (x, y) = point in x + y");
assert!(result.contains("let") && result.contains("in"));
}
#[test]
fn test_format_while_let() {
let result = format_code("while let Some(x) = iter.next() { x }");
assert!(result.contains("while") && result.contains("let"));
}
#[test]
fn test_format_string_interpolation() {
let result = format_code("f\"Hello {name}!\"");
assert!(result.contains("f\"") || result.contains("Hello"));
}
#[test]
fn test_format_string_interpolation_format_spec() {
let result = format_code("f\"Value: {x:02}\"");
assert!(!result.is_empty());
}
#[test]
fn test_format_actor_definition() {
let result = try_format("actor Counter { count: Int }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_effect_declaration() {
let result = format_code("effect IO { read() -> String, write(s: String) }");
assert!(result.contains("effect"));
}
#[test]
fn test_format_handle_expression() {
let result = format_code("handle expr with { op => value }");
assert!(result.contains("handle") || result.contains("with"));
}
#[test]
fn test_format_send() {
let result = try_format("send(actor, message)");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_loop() {
let result = format_code("loop { break }");
assert!(result.contains("loop"));
}
#[test]
fn test_format_pipeline() {
let result = format_code("data |> filter |> map");
assert!(result.contains("|>"));
}
#[test]
fn test_format_pre_increment() {
let result = format_code("++x");
assert!(result.contains("++"));
}
#[test]
fn test_format_post_increment() {
let result = format_code("x++");
assert!(result.contains("++"));
}
#[test]
fn test_format_pre_decrement() {
let result = format_code("--x");
assert!(result.contains("--"));
}
#[test]
fn test_format_post_decrement() {
let result = format_code("x--");
assert!(result.contains("--"));
}
#[test]
fn test_format_actor_send() {
let result = try_format("actor <- message");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_actor_query() {
let result = try_format("actor <? query");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_ask() {
let result = try_format("ask actor message");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_list_comprehension() {
let result = format_code("[x * 2 for x in list]");
assert!(result.contains("for"));
}
#[test]
fn test_format_list_comprehension_with_filter() {
let result = format_code("[x for x in list if x > 0]");
assert!(result.contains("for") && result.contains("if"));
}
#[test]
fn test_format_dict_comprehension() {
let result = format_code("{k: v for k in keys}");
assert!(result.contains("for"));
}
#[test]
fn test_format_set_comprehension() {
let result = format_code("{x for x in items}");
assert!(result.contains("for"));
}
#[test]
fn test_format_command() {
let result = try_format("`ls -la`");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_qualified_name() {
let result = try_format("std::io::read");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_type_alias() {
let result = format_code("type MyInt = Int");
assert!(result.contains("type") && result.contains("="));
}
#[test]
fn test_format_spread() {
let result = try_format("{ ...args }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_optional_method_call() {
let result = format_code("obj?.method()");
assert!(result.contains("?."));
}
#[test]
fn test_format_optional_method_call_with_args() {
let result = format_code("obj?.method(1, 2)");
assert!(result.contains("?.") && result.contains("method"));
}
#[test]
fn test_format_extension() {
let result = try_format("extension Int { fun double() { self * 2 } }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_reexport() {
let result = try_format("export { foo, bar } from module");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_macro_definition() {
let result = format_code("macro debug(x) { println(\"{:?}\", x) }");
assert!(result.contains("macro") || result.contains("debug"));
}
#[test]
fn test_format_macro_invocation() {
let result = format_code("println!(\"hello\")");
assert!(result.contains("!"));
}
#[test]
fn test_format_vec_repeat() {
let result = format_code("vec![0; 10]");
assert!(result.contains("vec!") || result.contains(";"));
}
#[test]
fn test_format_dataframe() {
let result = format_code("df![\"x\" => [1, 2, 3]]");
assert!(result.contains("df!") || result.contains("=>"));
}
#[test]
fn test_format_lazy() {
let result = format_code("lazy expensive_computation()");
assert!(result.contains("lazy"));
}
#[test]
fn test_format_class() {
let result = format_code("class Person { name: String, age: Int }");
assert!(result.contains("class") && result.contains("Person"));
}
#[test]
fn test_format_class_with_generics() {
let result = format_code("class Container<T> { value: T }");
assert!(result.contains("class") && result.contains("<T>"));
}
#[test]
fn test_format_with_tabs() {
use crate::quality::formatter_config::FormatterConfig;
let mut config = FormatterConfig::default();
config.use_tabs = true;
let formatter = crate::quality::formatter::Formatter::with_config(config);
let mut parser = Parser::new("fun foo() { x }");
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("fun") && result.contains("x"));
}
#[test]
fn test_format_with_custom_indent() {
use crate::quality::formatter_config::FormatterConfig;
let mut config = FormatterConfig::default();
config.indent_width = 2;
let formatter = crate::quality::formatter::Formatter::with_config(config);
let mut parser = Parser::new("{ x }");
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("x"));
}
#[test]
fn test_format_preserves_line_comment() {
let result = format_code("// this is a comment\n42");
assert!(result.contains("//") || result.contains("42"));
}
#[test]
fn test_format_preserves_doc_comment() {
let result = format_code("/// doc comment\nfun foo() { }");
assert!(result.contains("///") || result.contains("fun"));
}
#[test]
fn test_format_char_literal() {
let result = format_code("'a'");
assert!(result.contains("'a'") || result.contains("a"));
}
#[test]
fn test_format_byte_literal() {
let result = format_code("b'x'");
assert!(!result.is_empty());
}
#[test]
fn test_format_unit_literal() {
let result = format_code("()");
assert!(result.contains("()"));
}
#[test]
fn test_format_null_literal() {
let result = format_code("null");
assert!(result.contains("null"));
}
#[test]
fn test_format_atom_literal() {
let result = format_code(":ok");
assert!(result.contains(":ok") || result.contains("ok"));
}
#[test]
fn test_format_function_with_generic_type() {
let result = format_code("fun identity<T>(x: T) -> T { x }");
assert!(result.contains("fun") && result.contains("->"));
}
#[test]
fn test_format_function_with_tuple_type() {
let result = format_code("fun pair() -> (Int, Int) { (1, 2) }");
assert!(result.contains("->"));
}
#[test]
fn test_format_function_with_array_type() {
let result = format_code("fun zeros() -> [Int; 3] { [0, 0, 0] }");
assert!(result.contains("fun"));
}
#[test]
fn test_format_match_with_wildcard() {
let code = "match x { _ => 0 }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_match_with_tuple_pattern() {
let code = "match point { (x, y) => x + y }";
let result = format_code(code);
assert!(result.contains("match"));
}
#[test]
fn test_format_match_with_struct_pattern() {
let code = "match p { Point { x, y } => x + y }";
let result = format_code(code);
assert!(result.contains("match"));
}
#[test]
fn test_format_deeply_nested_blocks() {
let result = format_code("{ { { { 42 } } } }");
assert!(result.contains("42"));
}
#[test]
fn test_format_nested_function_calls() {
let result = format_code("foo(bar(baz(x)))");
assert!(result.contains("foo") && result.contains("bar") && result.contains("baz"));
}
#[test]
fn test_format_chained_method_calls() {
let result = format_code("x.foo().bar().baz()");
assert!(result.contains(".foo") && result.contains(".bar"));
}
#[test]
fn test_format_struct_literal_with_base() {
let result = format_code("Point { x: 1, ..base }");
assert!(result.contains("Point") && result.contains(".."));
}
#[test]
fn test_format_object_with_spread() {
let result = format_code("{ ...other, x: 1 }");
assert!(result.contains("..."));
}
#[test]
fn test_format_slice_start_only() {
let result = format_code("arr[1..]");
assert!(result.contains("[") && result.contains(".."));
}
#[test]
fn test_format_slice_end_only() {
let result = format_code("arr[..3]");
assert!(result.contains("[") && result.contains(".."));
}
#[test]
fn test_format_try_catch_finally() {
let result = try_format("try { risky() } catch (e) { handle(e) } finally { cleanup() }");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_async_lambda() {
let result = format_code("async |x| await fetch(x)");
assert!(result.contains("async") || result.contains("|"));
}
#[test]
fn test_format_import_default() {
let result = try_format("import default App from module");
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_dataframe_select() {
let result = format_code("df.select([\"a\", \"b\"])");
assert!(result.contains("select") || result.contains("df"));
}
#[test]
fn test_format_dataframe_filter() {
let result = format_code("df.filter(|row| row.x > 0)");
assert!(result.contains("filter") || result.contains("df"));
}
#[test]
fn test_format_empty_block() {
let result = format_code("{ }");
assert!(result.contains("{") && result.contains("}"));
}
#[test]
fn test_format_let_statement_only() {
let result = format_code("let x = 42");
assert!(result.contains("let") && result.contains("42"));
}
#[test]
fn test_format_sequential_lets() {
let code = "{ let x = 1\n let y = 2\n x + y }";
let result = format_code(code);
assert!(result.contains("let x") && result.contains("let y"));
}
#[test]
fn test_format_binary_and() {
let result = format_code("a && b");
assert!(result.contains("&&"));
}
#[test]
fn test_format_binary_or() {
let result = format_code("a || b");
assert!(result.contains("||"));
}
#[test]
fn test_format_binary_bitwise() {
let result = format_code("a & b | c ^ d");
assert!(result.contains("&") || result.contains("|"));
}
#[test]
fn test_format_binary_shift() {
let result = format_code("a << 2 >> 1");
assert!(result.contains("<<") || result.contains(">>"));
}
#[test]
fn test_format_unary_reference() {
let result = format_code("&x");
assert!(result.contains("&"));
}
#[test]
fn test_format_unary_deref() {
let result = format_code("*ptr");
assert!(result.contains("*"));
}
#[test]
fn test_format_compound_assign_div() {
let result = format_code("x /= 2");
assert!(result.contains("/=") || result.contains("/"));
}
#[test]
fn test_format_compound_assign_mod() {
let result = format_code("x %= 3");
assert!(result.contains("%=") || result.contains("%"));
}
#[test]
fn test_format_compound_assign_bitand() {
let result = format_code("x &= 0xFF");
assert!(result.contains("&=") || result.contains("&"));
}
#[test]
fn test_format_compound_assign_bitor() {
let result = format_code("x |= 1");
assert!(result.contains("|=") || result.contains("|"));
}
#[test]
fn test_format_compound_assign_xor() {
let result = format_code("x ^= mask");
assert!(result.contains("^=") || result.contains("^"));
}