#[cfg(test)]
mod tests {
use crate::frontend::ast::{Expr, ExprKind, Literal, UnaryOp};
use crate::frontend::parser::Parser;
use crate::quality::formatter::Formatter;
fn format_code(code: &str) -> String {
let mut parser = Parser::new(code);
let ast = parser.parse().expect("should parse");
let formatter = Formatter::new();
formatter.format(&ast).expect("should format")
}
fn try_format(code: &str) -> Result<String, String> {
let mut parser = Parser::new(code);
match parser.parse() {
Ok(ast) => {
let formatter = Formatter::new();
formatter.format(&ast).map_err(|e| e.to_string())
}
Err(e) => Err(format!("Parse error: {e:?}")),
}
}
fn make_lit(val: i64) -> Expr {
Expr::new(
ExprKind::Literal(Literal::Integer(val, None)),
Default::default(),
)
}
fn make_ident(name: &str) -> Expr {
Expr::new(ExprKind::Identifier(name.to_string()), Default::default())
}
#[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("^"));
}
#[test]
fn test_format_match_with_guard() {
let code = "match x { n if n > 0 => \"positive\", _ => \"other\" }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_match_with_or_pattern() {
let code = "match x { 1 | 2 | 3 => \"small\", _ => \"big\" }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_function_no_params() {
let result = format_code("fun greet() { \"hello\" }");
assert!(result.contains("fun") && result.contains("()"));
}
#[test]
fn test_format_function_many_params() {
let result = format_code("fun foo(a, b, c, d, e) { a + b + c + d + e }");
assert!(result.contains("fun") && result.contains(","));
}
#[test]
fn test_format_bool_true() {
let result = format_code("true");
assert_eq!(result.trim(), "true");
}
#[test]
fn test_format_bool_false() {
let result = format_code("false");
assert_eq!(result.trim(), "false");
}
#[test]
fn test_format_with_line_comment() {
let code = "// comment\nlet x = 1";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_with_doc_comment() {
let code = "/// doc comment\nfun foo() { 1 }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_with_block_comment() {
let code = "/* block */\nlet x = 1";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_comment_preservation_with_formatter_api() {
use crate::quality::formatter::Formatter;
let formatter = Formatter::new();
let code = "let x = 42";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("let") && result.contains("42"));
}
#[test]
fn test_formatter_with_source_set() {
use crate::quality::formatter::Formatter;
let mut formatter = Formatter::new();
let source = "let x = 42";
formatter.set_source(source);
let mut parser = Parser::new(source);
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("let") && result.contains("42"));
}
#[test]
fn test_formatter_source_none() {
use crate::quality::formatter::Formatter;
let formatter = Formatter::new(); let code = "let x = 42";
let mut parser = Parser::new(code);
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("let"));
}
#[test]
fn test_format_function_with_arrow_return_type() {
let code = "fun add(a: Int, b: Int) -> Int { a + b }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_let_with_type_annotation() {
let code = "let x: Int = 42";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_generic_function() {
let code = "fun identity<T>(x: T) -> T { x }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_preserves_structure() {
use crate::quality::formatter::Formatter;
let code = "let a = 1\nlet b = 2";
let mut formatter = Formatter::new();
formatter.set_source(code);
let mut parser = Parser::new(code);
let ast = parser.parse().expect("should parse");
let result = formatter.format(&ast).expect("should format");
assert!(result.contains("let a") && result.contains("let b"));
}
#[test]
fn test_format_nested_block_span() {
let code = "fun foo() { if true { 1 } else { 2 } }";
let result = format_code(code);
assert!(result.contains("fun") && result.contains("if"));
}
#[test]
fn test_format_deeply_nested_binary() {
let code = "1 + 2 + 3 + 4 + 5";
let result = format_code(code);
assert!(result.contains("+"));
}
#[test]
fn test_format_method_chain() {
let code = "x.foo().bar().baz()";
let result = format_code(code);
assert!(result.contains("foo") && result.contains("bar") && result.contains("baz"));
}
#[test]
fn test_format_complex_call_args() {
let code = "func(1, 2, 3, a + b, c * d)";
let result = format_code(code);
assert!(result.contains("func") && result.contains(","));
}
#[test]
fn test_format_while_with_break() {
let code = "while true { if done { break } }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_while_with_continue() {
let code = "while true { if skip { continue } }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_for_with_range() {
let code = "for i in 0..10 { print(i) }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_exclusive_range() {
let code = "0..10";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_inclusive_range() {
let code = "0..=10";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_lambda_three_params() {
let code = "|a, b, c| a + b + c";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_lambda_with_block() {
let code = "|x| { let y = x * 2; y }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_ok_variant() {
let code = "Ok(42)";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_err_variant() {
let code = "Err(\"error\")";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_some_variant() {
let code = "Some(42)";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_none_variant() {
let code = "None";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_await_expr() {
let code = "await fetch()";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_async_block_with_await() {
let code = "async { fetch().await }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_spawn_expr() {
let code = "spawn(counter)";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_try_expr() {
let code = "try { risky() } catch e { handle(e) }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_throw_expr() {
let code = "throw Error(\"oops\")";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_question_mark_operator() {
let code = "result?";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_type_cast_as() {
let code = "x as Int";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_array_init_repeat() {
let code = "[0; 10]";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_object_literal_multiple_fields() {
let code = "{ x: 1, y: 2, z: 3 }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_struct_literal_with_spread_base() {
let code = "Point { x: 1, ..default }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_slice_both() {
let code = "arr[1..5]";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_slice_from() {
let code = "arr[1..]";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_slice_to() {
let code = "arr[..5]";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_slice_all() {
let code = "arr[..]";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_if_let_some() {
let code = "if let Some(x) = opt { x }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_if_let_some_with_else() {
let code = "if let Some(x) = opt { x } else { 0 }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_optional_field() {
let code = "obj?.field";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_set_literal() {
let code = "{1, 2, 3}";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_dataframe_operation() {
let code = "df.filter(x > 0)";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_lazy_expr() {
let code = "lazy(expensive_computation())";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_empty_block_braces() {
let result = format_code("{}");
assert!(result.contains("{") && result.contains("}"));
}
#[test]
fn test_format_block_single_number() {
let result = format_code("{ 42 }");
assert!(result.contains("42"));
}
#[test]
fn test_format_nested_if_else() {
let code = "if a { if b { 1 } else { 2 } } else { 3 }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_return_without_value() {
let code = "return";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_break_with_number() {
let code = "break 42";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_block_multiple_lets() {
let code = "{ let a = 1; let b = 2; a + b }";
let result = try_format(code);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_format_loop_direct() {
let formatter = Formatter::new();
let body = make_lit(1);
let expr = Expr::new(
ExprKind::Loop {
body: Box::new(body),
label: None,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("loop"));
}
#[test]
fn test_format_send_direct() {
let formatter = Formatter::new();
let actor = make_ident("actor");
let message = make_lit(42);
let expr = Expr::new(
ExprKind::Send {
actor: Box::new(actor),
message: Box::new(message),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("send"));
}
#[test]
fn test_format_pre_increment_direct() {
let formatter = Formatter::new();
let target = make_ident("x");
let expr = Expr::new(
ExprKind::PreIncrement {
target: Box::new(target),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("++"));
}
#[test]
fn test_format_post_increment_direct() {
let formatter = Formatter::new();
let target = make_ident("x");
let expr = Expr::new(
ExprKind::PostIncrement {
target: Box::new(target),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("++"));
}
#[test]
fn test_format_pre_decrement_direct() {
let formatter = Formatter::new();
let target = make_ident("x");
let expr = Expr::new(
ExprKind::PreDecrement {
target: Box::new(target),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("--"));
}
#[test]
fn test_format_post_decrement_direct() {
let formatter = Formatter::new();
let target = make_ident("x");
let expr = Expr::new(
ExprKind::PostDecrement {
target: Box::new(target),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("--"));
}
#[test]
fn test_format_actor_send_direct() {
let formatter = Formatter::new();
let actor = make_ident("actor");
let message = make_lit(42);
let expr = Expr::new(
ExprKind::ActorSend {
actor: Box::new(actor),
message: Box::new(message),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(!result.is_empty());
}
#[test]
fn test_format_actor_query_direct() {
let formatter = Formatter::new();
let actor = make_ident("actor");
let message = make_lit(42);
let expr = Expr::new(
ExprKind::ActorQuery {
actor: Box::new(actor),
message: Box::new(message),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("?"));
}
#[test]
fn test_format_ask_direct() {
let formatter = Formatter::new();
let actor = make_ident("actor");
let message = make_lit(42);
let expr = Expr::new(
ExprKind::Ask {
actor: Box::new(actor),
message: Box::new(message),
timeout: None,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("ask"));
}
#[test]
fn test_format_ask_with_timeout_direct() {
let formatter = Formatter::new();
let actor = make_ident("actor");
let message = make_lit(42);
let timeout = make_lit(1000);
let expr = Expr::new(
ExprKind::Ask {
actor: Box::new(actor),
message: Box::new(message),
timeout: Some(Box::new(timeout)),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("ask"));
}
#[test]
fn test_format_import_all_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::ImportAll {
module: "std::io".to_string(),
alias: String::new(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("import") && result.contains("*"));
}
#[test]
fn test_format_import_default_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::ImportDefault {
module: "react".to_string(),
name: "React".to_string(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("import"));
}
#[test]
fn test_format_export_list_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::ExportList {
names: vec!["foo".to_string(), "bar".to_string()],
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("export"));
}
#[test]
fn test_format_export_default_direct() {
let formatter = Formatter::new();
let inner = make_ident("Component");
let expr = Expr::new(
ExprKind::ExportDefault {
expr: Box::new(inner),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("export") && result.contains("default"));
}
#[test]
fn test_format_qualified_name_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::QualifiedName {
module: "std::io".to_string(),
name: "read".to_string(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("::"));
}
#[test]
fn test_format_type_alias_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::TypeAlias {
name: "MyInt".to_string(),
target_type: crate::frontend::ast::Type {
kind: crate::frontend::ast::TypeKind::Named("Int".to_string()),
span: Default::default(),
},
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("type") && result.contains("MyInt"));
}
#[test]
fn test_format_spread_direct() {
let formatter = Formatter::new();
let inner = make_ident("args");
let expr = Expr::new(
ExprKind::Spread {
expr: Box::new(inner),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("..."));
}
#[test]
fn test_format_vec_repeat_direct() {
let formatter = Formatter::new();
let value = make_lit(0);
let count = make_lit(10);
let expr = Expr::new(
ExprKind::VecRepeat {
value: Box::new(value),
count: Box::new(count),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[") && result.contains(";"));
}
#[test]
fn test_format_lazy_direct() {
let formatter = Formatter::new();
let inner = make_lit(42);
let expr = Expr::new(
ExprKind::Lazy {
expr: Box::new(inner),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("lazy"));
}
#[test]
fn test_format_set_direct() {
let formatter = Formatter::new();
let items = vec![make_lit(1), make_lit(2), make_lit(3)];
let expr = Expr::new(ExprKind::Set(items), Default::default());
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("{") && result.contains("}"));
}
#[test]
fn test_format_none_direct() {
let formatter = Formatter::new();
let expr = Expr::new(ExprKind::None, Default::default());
let result = formatter.format(&expr).expect("should format");
assert_eq!(result, "None");
}
#[test]
fn test_format_ok_direct() {
let formatter = Formatter::new();
let value = make_lit(42);
let expr = Expr::new(
ExprKind::Ok {
value: Box::new(value),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("Ok"));
}
#[test]
fn test_format_err_direct() {
let formatter = Formatter::new();
let error = Expr::new(
ExprKind::Literal(Literal::String("error".to_string())),
Default::default(),
);
let expr = Expr::new(
ExprKind::Err {
error: Box::new(error),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("Err"));
}
#[test]
fn test_format_some_direct() {
let formatter = Formatter::new();
let value = make_lit(42);
let expr = Expr::new(
ExprKind::Some {
value: Box::new(value),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("Some"));
}
#[test]
fn test_format_try_direct() {
let formatter = Formatter::new();
let inner = make_ident("result");
let expr = Expr::new(
ExprKind::Try {
expr: Box::new(inner),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("?"));
}
#[test]
fn test_format_spawn_direct() {
let formatter = Formatter::new();
let actor = make_ident("MyActor");
let expr = Expr::new(
ExprKind::Spawn {
actor: Box::new(actor),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("spawn"));
}
#[test]
fn test_format_await_direct() {
let formatter = Formatter::new();
let inner = make_ident("future");
let expr = Expr::new(
ExprKind::Await {
expr: Box::new(inner),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("await"));
}
#[test]
fn test_format_async_block_direct() {
let formatter = Formatter::new();
let body = make_lit(42);
let expr = Expr::new(
ExprKind::AsyncBlock {
body: Box::new(body),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("async"));
}
#[test]
fn test_format_throw_direct() {
let formatter = Formatter::new();
let error = Expr::new(
ExprKind::Literal(Literal::String("error".to_string())),
Default::default(),
);
let expr = Expr::new(
ExprKind::Throw {
expr: Box::new(error),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("throw"));
}
#[test]
fn test_format_return_with_value_direct() {
let formatter = Formatter::new();
let value = make_lit(42);
let expr = Expr::new(
ExprKind::Return {
value: Some(Box::new(value)),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("return") && result.contains("42"));
}
#[test]
fn test_format_return_without_value_direct() {
let formatter = Formatter::new();
let expr = Expr::new(ExprKind::Return { value: None }, Default::default());
let result = formatter.format(&expr).expect("should format");
assert_eq!(result, "return");
}
#[test]
fn test_format_break_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::Break {
label: None,
value: None,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert_eq!(result, "break");
}
#[test]
fn test_format_break_with_value_direct() {
let formatter = Formatter::new();
let value = make_lit(42);
let expr = Expr::new(
ExprKind::Break {
label: None,
value: Some(Box::new(value)),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("break") && result.contains("42"));
}
#[test]
fn test_format_continue_direct() {
let formatter = Formatter::new();
let expr = Expr::new(ExprKind::Continue { label: None }, Default::default());
let result = formatter.format(&expr).expect("should format");
assert_eq!(result, "continue");
}
#[test]
fn test_format_unary_not_direct() {
let formatter = Formatter::new();
let operand = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
let expr = Expr::new(
ExprKind::Unary {
op: UnaryOp::Not,
operand: Box::new(operand),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("!"));
}
#[test]
fn test_format_unary_negate_direct() {
let formatter = Formatter::new();
let operand = make_lit(42);
let expr = Expr::new(
ExprKind::Unary {
op: UnaryOp::Negate,
operand: Box::new(operand),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("-"));
}
#[test]
fn test_format_range_exclusive_direct() {
let formatter = Formatter::new();
let start = make_lit(0);
let end = make_lit(10);
let expr = Expr::new(
ExprKind::Range {
start: Box::new(start),
end: Box::new(end),
inclusive: false,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains(".."));
}
#[test]
fn test_format_range_inclusive_direct() {
let formatter = Formatter::new();
let start = make_lit(0);
let end = make_lit(10);
let expr = Expr::new(
ExprKind::Range {
start: Box::new(start),
end: Box::new(end),
inclusive: true,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("..="));
}
#[test]
fn test_format_slice_direct() {
let formatter = Formatter::new();
let obj = make_ident("arr");
let start = make_lit(0);
let end = make_lit(5);
let expr = Expr::new(
ExprKind::Slice {
object: Box::new(obj),
start: Some(Box::new(start)),
end: Some(Box::new(end)),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[") && result.contains(".."));
}
#[test]
fn test_format_slice_from_direct() {
let formatter = Formatter::new();
let obj = make_ident("arr");
let start = make_lit(1);
let expr = Expr::new(
ExprKind::Slice {
object: Box::new(obj),
start: Some(Box::new(start)),
end: None,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[1..]"));
}
#[test]
fn test_format_slice_to_direct() {
let formatter = Formatter::new();
let obj = make_ident("arr");
let end = make_lit(5);
let expr = Expr::new(
ExprKind::Slice {
object: Box::new(obj),
start: None,
end: Some(Box::new(end)),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[..5]"));
}
#[test]
fn test_format_slice_full_direct() {
let formatter = Formatter::new();
let obj = make_ident("arr");
let expr = Expr::new(
ExprKind::Slice {
object: Box::new(obj),
start: None,
end: None,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[..]"));
}
#[test]
fn test_format_optional_field_access_direct() {
let formatter = Formatter::new();
let obj = make_ident("obj");
let expr = Expr::new(
ExprKind::OptionalFieldAccess {
object: Box::new(obj),
field: "name".to_string(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("?."));
}
#[test]
fn test_format_ternary_direct() {
let formatter = Formatter::new();
let condition = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
let then_expr = make_lit(1);
let else_expr = make_lit(2);
let expr = Expr::new(
ExprKind::Ternary {
condition: Box::new(condition),
true_expr: Box::new(then_expr),
false_expr: Box::new(else_expr),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("?") && result.contains(":"));
}
#[test]
fn test_format_array_init_direct() {
let formatter = Formatter::new();
let value = make_lit(0);
let size = make_lit(10);
let expr = Expr::new(
ExprKind::ArrayInit {
value: Box::new(value),
size: Box::new(size),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("[0; 10]"));
}
#[test]
fn test_format_module_direct() {
let formatter = Formatter::new();
let body = make_lit(42);
let expr = Expr::new(
ExprKind::Module {
name: "mymod".to_string(),
body: Box::new(body),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("mod") && result.contains("mymod"));
}
#[test]
fn test_format_module_declaration_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::ModuleDeclaration {
name: "utils".to_string(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("mod") && result.contains("utils"));
}
#[test]
fn test_format_reexport_direct() {
let formatter = Formatter::new();
let expr = Expr::new(
ExprKind::ReExport {
items: vec!["foo".to_string(), "bar".to_string()],
module: "other".to_string(),
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("export") && result.contains("from"));
}
#[test]
fn test_format_macro_direct() {
let formatter = Formatter::new();
let args = vec![make_lit(1), make_lit(2)];
let expr = Expr::new(
ExprKind::Macro {
name: "vec".to_string(),
args,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("vec"));
}
#[test]
fn test_format_macro_invocation_direct() {
let formatter = Formatter::new();
let args = vec![Expr::new(
ExprKind::Literal(Literal::String("hello".to_string())),
Default::default(),
)];
let expr = Expr::new(
ExprKind::MacroInvocation {
name: "println".to_string(),
args,
},
Default::default(),
);
let result = formatter.format(&expr).expect("should format");
assert!(result.contains("println!"));
}
}