mirror of
				https://github.com/roc-lang/roc.git
				synced 2025-11-03 22:13:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			6315 lines
		
	
	
	
		
			125 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			6315 lines
		
	
	
	
		
			125 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
#[macro_use]
 | 
						|
extern crate indoc;
 | 
						|
 | 
						|
#[cfg(test)]
 | 
						|
mod test_fmt {
 | 
						|
    use bumpalo::Bump;
 | 
						|
    use roc_fmt::def::fmt_defs;
 | 
						|
    use roc_fmt::header::fmt_header;
 | 
						|
    use roc_fmt::{Buf, MigrationFlags};
 | 
						|
    use roc_parse::ast::{Defs, Header, SpacesBefore};
 | 
						|
    use roc_parse::header::{self, parse_module_defs};
 | 
						|
    use roc_parse::state::State;
 | 
						|
    use roc_test_utils::assert_multiline_str_eq;
 | 
						|
    use roc_test_utils_dir::workspace_root;
 | 
						|
    use test_syntax::test_helpers::Input;
 | 
						|
 | 
						|
    fn check_formatting(expected: &'_ str) -> impl Fn(Input) + '_ {
 | 
						|
        let expected = expected.trim();
 | 
						|
        move |output| {
 | 
						|
            assert_multiline_str_eq!(expected, output.as_str());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    fn expr_formats_to(input: &str, expected: &str) {
 | 
						|
        Input::Expr(input.trim()).check_invariants(check_formatting(expected.trim()), true)
 | 
						|
    }
 | 
						|
 | 
						|
    fn expr_formats_same(input: &str) {
 | 
						|
        Input::Expr(input.trim()).check_invariants(check_formatting(input.trim()), true)
 | 
						|
    }
 | 
						|
 | 
						|
    fn fmt_module_and_defs<'a>(
 | 
						|
        arena: &Bump,
 | 
						|
        src: &str,
 | 
						|
        header: &SpacesBefore<'a, Header<'a>>,
 | 
						|
        state: State<'a>,
 | 
						|
        buf: &mut Buf<'_>,
 | 
						|
    ) {
 | 
						|
        fmt_header(buf, header);
 | 
						|
 | 
						|
        match parse_module_defs(arena, state, Defs::default()) {
 | 
						|
            Ok(loc_defs) => {
 | 
						|
                fmt_defs(buf, &loc_defs, 0);
 | 
						|
            }
 | 
						|
            Err(error) => {
 | 
						|
                let src = if src.len() > 1000 {
 | 
						|
                    "<source too long to display>"
 | 
						|
                } else {
 | 
						|
                    src
 | 
						|
                };
 | 
						|
                panic!(
 | 
						|
                    "Unexpected parse failure when parsing this for defs formatting:\n\n{src}\n\nParse error was:\n\n{error:?}\n\n"
 | 
						|
                )
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Not intended to be used directly in tests; please use module_formats_to or module_formats_same
 | 
						|
    fn expect_format_module_helper(src: &str, expected: &str) {
 | 
						|
        let arena = Bump::new();
 | 
						|
        let src = src.trim();
 | 
						|
        let expected = expected.trim();
 | 
						|
 | 
						|
        match header::parse_header(&arena, State::new(src.as_bytes())) {
 | 
						|
            Ok((actual, state)) => {
 | 
						|
                use roc_parse::normalize::Normalize;
 | 
						|
 | 
						|
                let flags = MigrationFlags::new(false);
 | 
						|
                let mut buf = Buf::new_in(&arena, flags);
 | 
						|
 | 
						|
                fmt_module_and_defs(&arena, src, &actual, state, &mut buf);
 | 
						|
 | 
						|
                let output = buf.as_str().trim();
 | 
						|
 | 
						|
                let (reparsed_ast, state) = header::parse_header(&arena, State::new(output.as_bytes())).unwrap_or_else(|err| {
 | 
						|
                    panic!(
 | 
						|
                        "After formatting, the source code no longer parsed!\n\nParse error was: {err:?}\n\nThe code that failed to parse:\n\n{output}\n\n"
 | 
						|
                    );
 | 
						|
                });
 | 
						|
 | 
						|
                let ast_normalized = actual.normalize(&arena);
 | 
						|
                let reparsed_ast_normalized = reparsed_ast.normalize(&arena);
 | 
						|
 | 
						|
                // HACK!
 | 
						|
                // We compare the debug format strings of the ASTs, because I'm finding in practice that _somewhere_ deep inside the ast,
 | 
						|
                // the PartialEq implementation is returning `false` even when the Debug-formatted impl is exactly the same.
 | 
						|
                // I don't have the patience to debug this right now, so let's leave it for another day...
 | 
						|
                // TODO: fix PartialEq impl on ast types
 | 
						|
                if format!("{ast_normalized:?}") != format!("{reparsed_ast_normalized:?}") {
 | 
						|
                    panic!(
 | 
						|
                        "Formatting bug; formatting didn't reparse to the same AST (after removing spaces)\n\n\
 | 
						|
                        * * * Source code before formatting:\n{src}\n\n\
 | 
						|
                        * * * Source code after formatting:\n{output}\n\n"
 | 
						|
                    );
 | 
						|
                }
 | 
						|
 | 
						|
                // Now verify that the resultant formatting is _stable_ - i.e. that it doesn't change again if re-formatted
 | 
						|
                let mut reformatted_buf = Buf::new_in(&arena, flags);
 | 
						|
 | 
						|
                fmt_module_and_defs(&arena, output, &reparsed_ast, state, &mut reformatted_buf);
 | 
						|
 | 
						|
                let reformatted = reformatted_buf.as_str().trim();
 | 
						|
 | 
						|
                if output != reformatted {
 | 
						|
                    eprintln!("Formatting bug; formatting is not stable. Reformatting the formatted code changed it again, as follows:\n\n");
 | 
						|
 | 
						|
                    assert_multiline_str_eq!(output, reformatted);
 | 
						|
                }
 | 
						|
 | 
						|
                // If everything was idempotent re-parsing worked, finally assert
 | 
						|
                // that the formatted code was what we expected it to be.
 | 
						|
                //
 | 
						|
                // Do this last because if there were any serious problems with the
 | 
						|
                // formatter (e.g. it wasn't idempotent), we want to know about
 | 
						|
                // those more than we want to know that the expectation failed!
 | 
						|
                assert_multiline_str_eq!(expected, output);
 | 
						|
            }
 | 
						|
            Err(error) => panic!("Unexpected parse failure when parsing this for module header formatting:\n\n{src:?}\n\nParse error was:\n\n{error:?}\n\n")
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    fn module_formats_to(input: &str, expected: &str) {
 | 
						|
        // First check that input formats to the expected version
 | 
						|
        expect_format_module_helper(input, expected);
 | 
						|
 | 
						|
        // Parse the expected result format it, asserting that it doesn't change
 | 
						|
        // It's important that formatting be stable / idempotent
 | 
						|
        expect_format_module_helper(expected, expected);
 | 
						|
    }
 | 
						|
 | 
						|
    fn module_formats_same(input: &str) {
 | 
						|
        module_formats_to(input, input);
 | 
						|
    }
 | 
						|
 | 
						|
    // STRING LITERALS
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn empty_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            ""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_with_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            # This variable is for greeting
 | 
						|
            a = "Hello"
 | 
						|
 | 
						|
            a
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn shebang_comment() {
 | 
						|
        // Correct shebangs are left alone
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            #!/usr/bin/env roc
 | 
						|
            x = 0
 | 
						|
 | 
						|
            x
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        // Incorrect shebang formatting from the past is fixed
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                # !/usr/bin/env roc
 | 
						|
                x = 0
 | 
						|
 | 
						|
                x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                #!/usr/bin/env roc
 | 
						|
                x = 0
 | 
						|
 | 
						|
                x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        // Other whitespace from the user is left alone
 | 
						|
        expr_formats_to(
 | 
						|
            &format!(
 | 
						|
                indoc!(
 | 
						|
                    r#"
 | 
						|
                    #  !/usr/bin/env roc{space}
 | 
						|
                    x = 0
 | 
						|
 | 
						|
                    x
 | 
						|
                    "#
 | 
						|
                ),
 | 
						|
                space = " "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                #  !/usr/bin/env roc
 | 
						|
                x = 0
 | 
						|
 | 
						|
                x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comment_with_trailing_space() {
 | 
						|
        expr_formats_to(
 | 
						|
            &format!(
 | 
						|
                indoc!(
 | 
						|
                    r"
 | 
						|
            # first comment{space}
 | 
						|
            x = 0 # second comment{space}
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
                ),
 | 
						|
                space = " ",
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            # first comment
 | 
						|
            x = 0 # second comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_with_inline_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 0 # comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0# comment
 | 
						|
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0 # comment
 | 
						|
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0# comment
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0 # comment
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0  # comment
 | 
						|
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 0 # comment
 | 
						|
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_with_comment_and_extra_space() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                # This variable is for greeting
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                a = "Hello"
 | 
						|
 | 
						|
                a
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                # This variable is for greeting
 | 
						|
                a = "Hello"
 | 
						|
 | 
						|
                a
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn type_annotation_allow_blank_line_before_and_after_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    # comment
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    firstName : Str,
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    firstName : Str,
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    lastName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    lastName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    # comment
 | 
						|
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                person : {
 | 
						|
                    firstName : Str,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    lastName : Str,
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_allow_blank_line_before_and_after_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
                    # comment 1
 | 
						|
                    lastName: "last",
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName: "last",
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
                    lastName: "last",
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName: "last",
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName: "last",
 | 
						|
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                person = {
 | 
						|
                    firstName: "first",
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    lastName: "last",
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                }
 | 
						|
 | 
						|
                person
 | 
						|
                "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
 | 
						|
                        # comment
 | 
						|
 | 
						|
                        firstName: "first",
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        # comment
 | 
						|
 | 
						|
                        firstName: "first",
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
                        lastName: "last",
 | 
						|
 | 
						|
                        # comment
 | 
						|
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
                        lastName: "last",
 | 
						|
 | 
						|
                        # comment
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
 | 
						|
 | 
						|
                        # comment 1
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
 | 
						|
                        # comment 1
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
                        # comment 1
 | 
						|
 | 
						|
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
                        # comment 1
 | 
						|
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
 | 
						|
 | 
						|
                        # comment 1
 | 
						|
 | 
						|
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    person = {
 | 
						|
                        firstName: "first",
 | 
						|
 | 
						|
                        # comment 1
 | 
						|
 | 
						|
                        lastName: "last",
 | 
						|
                    }
 | 
						|
 | 
						|
                    person
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn list_allow_blank_line_before_and_after_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    # comment
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    1,
 | 
						|
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
 | 
						|
                    1,
 | 
						|
                    # comment 2
 | 
						|
                    # comment 3
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
        ));
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    0,
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    0,
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    1,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    1,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    # comment
 | 
						|
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                list = [
 | 
						|
                    0,
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    1,
 | 
						|
                ]
 | 
						|
 | 
						|
                list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn force_space_at_beginning_of_comment() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                #comment
 | 
						|
                f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                # comment
 | 
						|
                f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn func_def() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                f = \x, y ->
 | 
						|
                    x
 | 
						|
 | 
						|
                f 4
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn new_line_above_return() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                f = \x, y ->
 | 
						|
                    y = 4
 | 
						|
                    z = 8
 | 
						|
                    x
 | 
						|
                "string"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                f = \x, y ->
 | 
						|
                    y = 4
 | 
						|
                    z = 8
 | 
						|
                    x
 | 
						|
                "string"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            f = \x, y ->
 | 
						|
                a = 3
 | 
						|
                b = 6
 | 
						|
 | 
						|
                c
 | 
						|
 | 
						|
            "string"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn basic_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            "blah"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn escaped_unicode_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            "unicode: \u(A00A)!"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn escaped_quote_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            "\""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn empty_block_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            """
 | 
						|
            """
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn oneline_empty_block_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """"""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """
 | 
						|
                """
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn basic_block_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """griffin"""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                "griffin"
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_basic_block_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """griffin
 | 
						|
                harpy"""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """
 | 
						|
                griffin
 | 
						|
                harpy
 | 
						|
                """
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn newlines_block_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """griffin
 | 
						|
                        harpy
 | 
						|
                phoenix"""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                """
 | 
						|
                griffin
 | 
						|
                        harpy
 | 
						|
                phoenix
 | 
						|
                """
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn quotes_block_string_single_segment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            """
 | 
						|
            "griffin"
 | 
						|
            """
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn quotes_block_string() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            """
 | 
						|
 | 
						|
            "" \""" ""\"
 | 
						|
 | 
						|
            """
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn zero() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn zero_point_zero() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            0.0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn int_with_underscores() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            1_23_456
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn float_with_underscores() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            1_23_456.7_89_10
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_arg_closure() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            \a, b, c -> a b c
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn destructure_tag_closure() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            \Foo a -> Foo a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn destructure_nested_tag_closure() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            \Foo (Bar a) -> Foo (Bar a)
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // DEFS
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_def() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn two_defs() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
            y = 10
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 5
 | 
						|
 | 
						|
 | 
						|
                y = 10
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 5
 | 
						|
 | 
						|
                y = 10
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn excess_parens() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = (5)
 | 
						|
 | 
						|
 | 
						|
                y = ((10))
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 5
 | 
						|
 | 
						|
                y = 10
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn defs_with_defs() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x =
 | 
						|
                    y = 4
 | 
						|
                    z = 8
 | 
						|
                    w
 | 
						|
 | 
						|
                x
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comment_between_two_defs() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
            # Hello
 | 
						|
            y = 10
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
            # Hello
 | 
						|
            # two comments
 | 
						|
            y = 10
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
            # Hello
 | 
						|
            # two comments
 | 
						|
            y = 10
 | 
						|
 | 
						|
            # v-- This is the return value
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn space_between_comments() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                # 9
 | 
						|
 | 
						|
                # A
 | 
						|
                # B
 | 
						|
 | 
						|
                # C
 | 
						|
                9
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                # 9
 | 
						|
                # A
 | 
						|
                # B
 | 
						|
                # C
 | 
						|
                9
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn reduce_space_between_comments() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                # First
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                # Second
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                # First
 | 
						|
                # Second
 | 
						|
                x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f = \x ->
 | 
						|
                    # 1st
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                    # 2nd
 | 
						|
                    x
 | 
						|
 | 
						|
                f 4
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f = \x ->
 | 
						|
                    # 1st
 | 
						|
 | 
						|
                    # 2nd
 | 
						|
                    x
 | 
						|
 | 
						|
                f 4
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn doesnt_detect_comment_in_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            # One Comment # Still one Comment
 | 
						|
            9
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn parenthetical_def() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            (UserId user_id) = 5
 | 
						|
            y = 10
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            # A
 | 
						|
            (UserId user_id) = 5
 | 
						|
            # B
 | 
						|
            y = 10
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_destructuring() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { x, y } = 5
 | 
						|
 | 
						|
            { x: 5 } = { x: 5 }
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_field_destructuring() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                when foo is
 | 
						|
                    { x: 5 } ->
 | 
						|
                        42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn lambda_returns_record() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                to_record = \_ -> {
 | 
						|
                    x: 1,
 | 
						|
                    y: 2,
 | 
						|
                    z: 3,
 | 
						|
                }
 | 
						|
 | 
						|
                to_record
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    func = \_ ->
 | 
						|
                        { x: 1, y: 2, z: 3 }
 | 
						|
 | 
						|
                    func
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                to_record = \_ ->
 | 
						|
                    val = 0
 | 
						|
 | 
						|
                    {
 | 
						|
                        x: 1,
 | 
						|
                        y: 2,
 | 
						|
                        z: 3,
 | 
						|
                    }
 | 
						|
 | 
						|
                to_record
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    to_record = \_ ->
 | 
						|
                        {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
 | 
						|
                    to_record
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    to_record = \_ -> {
 | 
						|
                        x: 1,
 | 
						|
                        y: 2,
 | 
						|
                        z: 3,
 | 
						|
                    }
 | 
						|
 | 
						|
                    to_record
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn lambda_returns_list() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                to_list = \_ -> [
 | 
						|
                    1,
 | 
						|
                    2,
 | 
						|
                    3,
 | 
						|
                ]
 | 
						|
 | 
						|
                to_list
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    func = \_ ->
 | 
						|
                        [1, 2, 3]
 | 
						|
 | 
						|
                    func
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                to_list = \_ ->
 | 
						|
                    val = 0
 | 
						|
 | 
						|
                    [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                        3,
 | 
						|
                    ]
 | 
						|
 | 
						|
                to_list
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    to_list = \_ ->
 | 
						|
                        [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
 | 
						|
                    to_list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    to_list = \_ -> [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                        3,
 | 
						|
                    ]
 | 
						|
 | 
						|
                    to_list
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_list_func_arg() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    result = func arg [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                        3,
 | 
						|
                    ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg
 | 
						|
                        [ 1, 2, 3 ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func
 | 
						|
                        arg
 | 
						|
                        [1, 2, 3]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                        3,
 | 
						|
                    ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
                        arg
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func
 | 
						|
                        [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
                        arg
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        // TODO: do we want to override the user's intent like this?
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg
 | 
						|
                        [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                        3,
 | 
						|
                    ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    result = func
 | 
						|
                        arg
 | 
						|
                        [
 | 
						|
                            1,
 | 
						|
                            2,
 | 
						|
                            3,
 | 
						|
                        ]
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_record_func_arg() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                result = func arg {
 | 
						|
                    x: 1,
 | 
						|
                    y: 2,
 | 
						|
                    z: 3,
 | 
						|
                }
 | 
						|
 | 
						|
                result
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg
 | 
						|
                        { x: 1, y: 2, z: 3 }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func
 | 
						|
                        arg
 | 
						|
                        { x: 1, y: 2, z: 3 }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg {
 | 
						|
                        x: 1,
 | 
						|
                        y: 2,
 | 
						|
                        z: 3,
 | 
						|
                    }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
                        arg
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func
 | 
						|
                        {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
                        arg
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        // TODO: do we want to override the user's intent like this?
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg
 | 
						|
                        {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    result = func arg {
 | 
						|
                        x: 1,
 | 
						|
                        y: 2,
 | 
						|
                        z: 3,
 | 
						|
                    }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    result = func
 | 
						|
                        arg
 | 
						|
                        {
 | 
						|
                            x: 1,
 | 
						|
                            y: 2,
 | 
						|
                            z: 3,
 | 
						|
                        }
 | 
						|
 | 
						|
                    result
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_updating() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { shoes & leftShoe: nothing }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                {   shoes  &  rightShoe : nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes & rightShoe: nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                {   shoes  &  rightShoe : nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes & rightShoe: nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { shoes &
 | 
						|
                rightShoe: newRightShoe,
 | 
						|
                leftShoe: newLeftShoe,
 | 
						|
            }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes
 | 
						|
                    & rightShoe: bareFoot
 | 
						|
                    , leftShoe: bareFoot }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes &
 | 
						|
                    rightShoe: bareFoot,
 | 
						|
                    leftShoe: bareFoot,
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_builder() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { shoes <- leftShoe: nothing }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                {   shoes  <-  rightShoe : nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes <- rightShoe: nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                {   shoes  <-  rightShoe : nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes <- rightShoe: nothing }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { shoes <-
 | 
						|
                rightShoe,
 | 
						|
                leftShoe: newLeftShoe,
 | 
						|
            }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            { shoes <-
 | 
						|
                # some comment
 | 
						|
                rightShoe,
 | 
						|
                # some other comment
 | 
						|
                leftShoe: newLeftShoe,
 | 
						|
            }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes
 | 
						|
                    <- rightShoe: bareFoot
 | 
						|
                    , leftShoe: bareFoot }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes <-
 | 
						|
                    rightShoe: bareFoot,
 | 
						|
                    leftShoe: bareFoot,
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes
 | 
						|
                    <- rightShoe: bareFoot, # some comment
 | 
						|
                    leftShoe: bareFoot }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { shoes <-
 | 
						|
                    rightShoe: bareFoot,
 | 
						|
                    # some comment
 | 
						|
                    leftShoe: bareFoot,
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn final_comments_in_records() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            {
 | 
						|
                x: 42,
 | 
						|
                # comment
 | 
						|
            }"
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            {
 | 
						|
                x: 42,
 | 
						|
                # comment
 | 
						|
                # other comment
 | 
						|
            }"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn final_comments_without_comma_in_records() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                # comment 1
 | 
						|
                x: 42 # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                # comment 1
 | 
						|
                x: 42,
 | 
						|
                # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiple_final_comments_without_comma_in_records() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                x: 42 # comment 1
 | 
						|
                # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                x: 42,
 | 
						|
                # comment 1
 | 
						|
                # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiple_final_comments_with_comma_in_records() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                x: 42, # comment 1
 | 
						|
                # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
                y: 41,
 | 
						|
                x: 42,
 | 
						|
                # comment 1
 | 
						|
                # comment 2
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn trailing_comma_in_record_annotation() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f: {                    y : Int *,
 | 
						|
                                         x : Int * ,
 | 
						|
                   }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {
 | 
						|
                    y : Int *,
 | 
						|
                    x : Int *,
 | 
						|
                }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn trailing_comma_in_record_annotation_same() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                f : {
 | 
						|
                    y : Int *,
 | 
						|
                    x : Int *,
 | 
						|
                }
 | 
						|
 | 
						|
                f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f :
 | 
						|
                        {
 | 
						|
                            y : Int *,
 | 
						|
                            x : Int *,
 | 
						|
                        }
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f : {
 | 
						|
                        y : Int *,
 | 
						|
                        x : Int *,
 | 
						|
                    }
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_type_definition() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                f :
 | 
						|
                    Int *
 | 
						|
 | 
						|
                f"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_empty_record_type_definition() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                f :
 | 
						|
                    {}
 | 
						|
 | 
						|
                f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f :
 | 
						|
                        {
 | 
						|
                        }
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f : {
 | 
						|
                    }
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn type_definition_comment_after_colon() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : # comment
 | 
						|
                    {}
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f :
 | 
						|
                    # comment
 | 
						|
                    {}
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn type_definition_add_space_around_optional_record() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : { a ?Str }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : { a ? Str }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {
 | 
						|
                    a ?Str,
 | 
						|
                }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {
 | 
						|
                    a ? Str,
 | 
						|
                }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    #[ignore]
 | 
						|
    fn final_comment_in_empty_record_type_definition() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f :
 | 
						|
                    { # comment
 | 
						|
                    }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {
 | 
						|
                    # comment
 | 
						|
                }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_curly_brace_type() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : {
 | 
						|
                    a : Int,
 | 
						|
                }
 | 
						|
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x :
 | 
						|
                    { a : Int }
 | 
						|
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_brace_type() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : [
 | 
						|
                    Int,
 | 
						|
                ]
 | 
						|
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x :
 | 
						|
                    [Int]
 | 
						|
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_fn_signature() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                foo :
 | 
						|
                    Str,
 | 
						|
                    U64
 | 
						|
                    -> Bool
 | 
						|
 | 
						|
                foo
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                    foo :
 | 
						|
                        Str, Int, U64 -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
                        Str,
 | 
						|
                        U64 -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
                        Str,
 | 
						|
                        U64
 | 
						|
                        -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
 | 
						|
                        Str,
 | 
						|
                        U64
 | 
						|
 | 
						|
                        -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
                        Str,
 | 
						|
                        U64
 | 
						|
                        -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
 | 
						|
                        Str, U64 -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    foo :
 | 
						|
                        Str, U64 -> Bool
 | 
						|
 | 
						|
                    foo
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn final_comment_record_annotation() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f :
 | 
						|
                    {
 | 
						|
                        x: Int * # comment 1
 | 
						|
                        ,
 | 
						|
                        # comment 2
 | 
						|
                    }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {
 | 
						|
                    x : Int *, # comment 1
 | 
						|
                    # comment 2
 | 
						|
                }
 | 
						|
 | 
						|
                f"
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_closure() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a -> a
 | 
						|
 | 
						|
            identity 42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a ->
 | 
						|
                a
 | 
						|
 | 
						|
            identity 44
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a -> a
 | 
						|
 | 
						|
            # Hello
 | 
						|
            identity 40
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    identity = \a
 | 
						|
                        -> a
 | 
						|
 | 
						|
                    identity 41
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    identity = \a -> a
 | 
						|
 | 
						|
                    identity 41
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    identity = \a
 | 
						|
                        ->
 | 
						|
                            a + b
 | 
						|
 | 
						|
                    identity 4010
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    identity = \a ->
 | 
						|
                        a + b
 | 
						|
 | 
						|
                    identity 4010
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a, b -> a
 | 
						|
 | 
						|
            identity 43
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        // expr_formats_same(indoc!(
 | 
						|
        //     r"
 | 
						|
        //    identity =
 | 
						|
        //        \{
 | 
						|
        //            x,
 | 
						|
        //            y
 | 
						|
        //         }
 | 
						|
        //        -> a
 | 
						|
        //
 | 
						|
        //    identity 43
 | 
						|
        //    "
 | 
						|
        // ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a,
 | 
						|
                b,
 | 
						|
                # it's c!!
 | 
						|
                c
 | 
						|
                -> a
 | 
						|
 | 
						|
            identity 43
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn closure_multiline_pattern() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            identity = \a,
 | 
						|
                b,
 | 
						|
                # it's c!!
 | 
						|
                c
 | 
						|
                -> a
 | 
						|
 | 
						|
            identity 43
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // LIST
 | 
						|
    #[test]
 | 
						|
    fn empty_list() {
 | 
						|
        expr_formats_same("[]");
 | 
						|
        expr_formats_to("[     ]", "[]");
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn one_item_list() {
 | 
						|
        expr_formats_same(indoc!("[4]"));
 | 
						|
        expr_formats_to(indoc!("[ 4 ]"), indoc!("[4]"));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn two_item_list() {
 | 
						|
        expr_formats_same(indoc!("[7, 8]"));
 | 
						|
        expr_formats_to(indoc!("[   7  ,   8  ]"), indoc!("[7, 8]"));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_list() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            [
 | 
						|
                7,
 | 
						|
                8,
 | 
						|
                9,
 | 
						|
            ]
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [ 17
 | 
						|
                , 18
 | 
						|
                , 19
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    17,
 | 
						|
                    18,
 | 
						|
                    19,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [ 27
 | 
						|
 | 
						|
                , 28
 | 
						|
 | 
						|
 | 
						|
                , 29
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    27,
 | 
						|
                    28,
 | 
						|
                    29,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    157, 158,
 | 
						|
                    159
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    157,
 | 
						|
                    158,
 | 
						|
                    159,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    557, 648,
 | 
						|
                    759, 837
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    557,
 | 
						|
                    648,
 | 
						|
                    759,
 | 
						|
                    837,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    257, 358,
 | 
						|
                    # Hey!
 | 
						|
                    459
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    257,
 | 
						|
                    358,
 | 
						|
                    # Hey!
 | 
						|
                    459,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                # Thirty Seven
 | 
						|
 | 
						|
                37
 | 
						|
                # Thirty Eight
 | 
						|
                , 38
 | 
						|
 | 
						|
 | 
						|
                , 39
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    # Thirty Seven
 | 
						|
 | 
						|
                    37,
 | 
						|
                    # Thirty Eight
 | 
						|
                    38,
 | 
						|
                    39,
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [ # 47!
 | 
						|
                # Top 47
 | 
						|
                  47
 | 
						|
                # Bottom 47
 | 
						|
                # Top 48
 | 
						|
                , 48
 | 
						|
                # Bottom 48
 | 
						|
                # Top 49
 | 
						|
                , 49
 | 
						|
                # Bottom 49
 | 
						|
                # 49!
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    # 47!
 | 
						|
                    # Top 47
 | 
						|
                    47,
 | 
						|
                    # Bottom 47
 | 
						|
                    # Top 48
 | 
						|
                    48,
 | 
						|
                    # Bottom 48
 | 
						|
                    # Top 49
 | 
						|
                    49,
 | 
						|
                    # Bottom 49
 | 
						|
                    # 49!
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
    #[test]
 | 
						|
    fn ending_comments_in_list() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [ # Top 49
 | 
						|
                 49
 | 
						|
                # Bottom 49
 | 
						|
                ,
 | 
						|
                # 49!
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                [
 | 
						|
                    # Top 49
 | 
						|
                    49,
 | 
						|
                    # Bottom 49
 | 
						|
                    # 49!
 | 
						|
                ]
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
    #[test]
 | 
						|
    fn multi_line_list_def() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                l = [
 | 
						|
                    1,
 | 
						|
                    2,
 | 
						|
                ]
 | 
						|
 | 
						|
                l
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                l =
 | 
						|
                    [1, 2]
 | 
						|
 | 
						|
                l
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                l =
 | 
						|
                    [
 | 
						|
                        1,
 | 
						|
                        2,
 | 
						|
                    ]
 | 
						|
 | 
						|
                l
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                l = [
 | 
						|
                    1,
 | 
						|
                    2,
 | 
						|
                ]
 | 
						|
 | 
						|
                l
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                results = [
 | 
						|
                    Ok 4,
 | 
						|
                    Ok 5
 | 
						|
                    ]
 | 
						|
 | 
						|
                allOks results
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                results = [
 | 
						|
                    Ok 4,
 | 
						|
                    Ok 5,
 | 
						|
                ]
 | 
						|
 | 
						|
                allOks results
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    results =
 | 
						|
                        # Let's count past 6
 | 
						|
                        [
 | 
						|
                        Ok 6,
 | 
						|
                        Err CountError
 | 
						|
                        ]
 | 
						|
 | 
						|
                    allOks results
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    results =
 | 
						|
                        # Let's count past 6
 | 
						|
                        [
 | 
						|
                            Ok 6,
 | 
						|
                            Err CountError,
 | 
						|
                        ]
 | 
						|
 | 
						|
                    allOks results
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    // RECORD LITERALS
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn empty_record() {
 | 
						|
        expr_formats_same("{}");
 | 
						|
        expr_formats_to("{ }", "{}");
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn empty_record_patterns() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    f = \{  } -> "Hello World"
 | 
						|
 | 
						|
                    f
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    f = \{} -> "Hello World"
 | 
						|
 | 
						|
                    f
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f = \a, b -> {  }
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    f = \a, b -> {}
 | 
						|
 | 
						|
                    f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    { } <- f a b
 | 
						|
 | 
						|
                    {}
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    {} <- f a b
 | 
						|
 | 
						|
                    {}
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    #[ignore]
 | 
						|
    fn empty_record_with_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            {
 | 
						|
                # comment
 | 
						|
            }"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    #[ignore]
 | 
						|
    fn empty_record_with_newline() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            {
 | 
						|
            }"
 | 
						|
            ),
 | 
						|
            "{}",
 | 
						|
        );
 | 
						|
    }
 | 
						|
    #[test]
 | 
						|
    fn one_field() {
 | 
						|
        expr_formats_same("{ x: 4 }");
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn two_fields() {
 | 
						|
        expr_formats_same("{ x: 4, y: 42 }");
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn two_fields_newline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            {
 | 
						|
                x: 4,
 | 
						|
                y: 42,
 | 
						|
            }
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_record_def() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                pos = {
 | 
						|
                    x: 4,
 | 
						|
                    y: 11,
 | 
						|
                    z: 16,
 | 
						|
                }
 | 
						|
 | 
						|
                pos
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                pos =
 | 
						|
                    { x: 4, y: 11, z: 16 }
 | 
						|
 | 
						|
                pos
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                my_def =
 | 
						|
                    list = [
 | 
						|
                        a,
 | 
						|
                        b,
 | 
						|
                    ]
 | 
						|
 | 
						|
                    {
 | 
						|
                        c,
 | 
						|
                        d,
 | 
						|
                    }
 | 
						|
 | 
						|
                my_def
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    pos =
 | 
						|
                        {
 | 
						|
                            x: 4,
 | 
						|
                            y: 11,
 | 
						|
                            z: 16,
 | 
						|
                        }
 | 
						|
 | 
						|
                    pos
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    pos = {
 | 
						|
                        x: 4,
 | 
						|
                        y: 11,
 | 
						|
                        z: 16,
 | 
						|
                    }
 | 
						|
 | 
						|
                    pos
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                pos = {
 | 
						|
                        x: 5,
 | 
						|
                        y: 10,
 | 
						|
                    }
 | 
						|
 | 
						|
                pos
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                pos = {
 | 
						|
                    x: 5,
 | 
						|
                    y: 10,
 | 
						|
                }
 | 
						|
 | 
						|
                pos
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn two_fields_center_newline() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                { x: 4,
 | 
						|
                    y: 42
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                {
 | 
						|
                    x: 4,
 | 
						|
                    y: 42,
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn one_unnamed_field() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            foo = 4
 | 
						|
 | 
						|
            { foo }
 | 
						|
        "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // IF
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_if() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if foo bar then a b c else d e f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if foo (a b c) then a b c else d e f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_if_condition() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if
 | 
						|
                waterWillBoil pressure temperature
 | 
						|
            then
 | 
						|
                turnOnAc
 | 
						|
            else
 | 
						|
                identity
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_if_condition_with_spaces() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
 | 
						|
 | 
						|
                    willBoil home water
 | 
						|
 | 
						|
 | 
						|
                then
 | 
						|
                    \_ -> leave
 | 
						|
 | 
						|
                else
 | 
						|
                    identity
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    willBoil home water
 | 
						|
                then
 | 
						|
                    \_ -> leave
 | 
						|
                else
 | 
						|
                    identity
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_if_condition_with_multi_line_expr_1() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if
 | 
						|
                snowWillFall
 | 
						|
                    pressure
 | 
						|
                    temperature
 | 
						|
            then
 | 
						|
                bundleUp
 | 
						|
            else
 | 
						|
                identity
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_if_condition_with_multi_line_expr_2() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            if
 | 
						|
                1
 | 
						|
                == 2
 | 
						|
            then
 | 
						|
                "yes"
 | 
						|
            else
 | 
						|
                "no"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn if_removes_newlines_from_else() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    isPrime 8
 | 
						|
                then
 | 
						|
                    nothing
 | 
						|
                else
 | 
						|
                    # C
 | 
						|
                    # D
 | 
						|
 | 
						|
                    # E
 | 
						|
                    # F
 | 
						|
 | 
						|
                    just (div 1 8)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    isPrime 8
 | 
						|
                then
 | 
						|
                    nothing
 | 
						|
                else
 | 
						|
                    # C
 | 
						|
                    # D
 | 
						|
                    # E
 | 
						|
                    # F
 | 
						|
                    just (div 1 8)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn if_removes_newlines_from_then() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    isPrime 9
 | 
						|
                then
 | 
						|
                    # EE
 | 
						|
                    # FF
 | 
						|
 | 
						|
                    nothing
 | 
						|
 | 
						|
                    # GG
 | 
						|
 | 
						|
                else
 | 
						|
                    just (div 1 9)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    isPrime 9
 | 
						|
                then
 | 
						|
                    # EE
 | 
						|
                    # FF
 | 
						|
                    nothing
 | 
						|
                    # GG
 | 
						|
                else
 | 
						|
                    just (div 1 9)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn if_removes_newlines_from_condition() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
 | 
						|
                    # Is
 | 
						|
 | 
						|
                    # It
 | 
						|
 | 
						|
                    isPrime 10
 | 
						|
 | 
						|
                    # Prime?
 | 
						|
 | 
						|
                then
 | 
						|
                    nothing
 | 
						|
                else
 | 
						|
                    just (div 1 10)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if
 | 
						|
                    # Is
 | 
						|
                    # It
 | 
						|
                    isPrime 10
 | 
						|
                    # Prime?
 | 
						|
                then
 | 
						|
                    nothing
 | 
						|
                else
 | 
						|
                    just (div 1 10)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_if() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if lessThan four five then
 | 
						|
                    four
 | 
						|
 | 
						|
 | 
						|
                else
 | 
						|
                    five
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if lessThan four five then
 | 
						|
                    four
 | 
						|
                else
 | 
						|
                    five
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if lessThan three four then
 | 
						|
 | 
						|
 | 
						|
                    three
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                else
 | 
						|
 | 
						|
 | 
						|
                    four
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if lessThan three four then
 | 
						|
                    three
 | 
						|
                else
 | 
						|
                    four
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if foo bar then
 | 
						|
                a b c
 | 
						|
            else
 | 
						|
                d e f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn early_return_else() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if foo then
 | 
						|
                bar
 | 
						|
                else
 | 
						|
 | 
						|
            baz
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if thing then
 | 
						|
                    whatever
 | 
						|
                    else
 | 
						|
                too close
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if thing then
 | 
						|
                    whatever
 | 
						|
                    else
 | 
						|
 | 
						|
                too close
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if isGrowing plant then
 | 
						|
                    LetBe
 | 
						|
                    else
 | 
						|
 | 
						|
                    Water
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                if isGrowing plant then
 | 
						|
                    LetBe
 | 
						|
                    else
 | 
						|
 | 
						|
                Water
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_application() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            combine
 | 
						|
                peanutButter
 | 
						|
                chocolate
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn partial_multi_line_application() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                mix vodka
 | 
						|
                    tonic
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                mix
 | 
						|
                    vodka
 | 
						|
                    tonic
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f
 | 
						|
                    a b c
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f
 | 
						|
                    a
 | 
						|
                    b
 | 
						|
                    c
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    // WHEN
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn integer_when() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when b is
 | 
						|
                1 ->
 | 
						|
                    1
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    2
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn integer_when_with_space() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when year is
 | 
						|
                    1999 ->
 | 
						|
 | 
						|
 | 
						|
                        1
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                    _ ->
 | 
						|
 | 
						|
                        0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when year is
 | 
						|
                    1999 ->
 | 
						|
                        1
 | 
						|
 | 
						|
                    _ ->
 | 
						|
                        0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_comments() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when b is
 | 
						|
                # look at cases
 | 
						|
                1 -> # when 1
 | 
						|
                    1
 | 
						|
 | 
						|
                # important
 | 
						|
                # fall through
 | 
						|
                _ ->
 | 
						|
                    # case 2
 | 
						|
                    # more comment
 | 
						|
                    2
 | 
						|
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_integer_comments() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                when 0 is
 | 
						|
                    1 # comment
 | 
						|
                    | 2 -> "a"
 | 
						|
 | 
						|
                    _ -> "b"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn nested_when() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when b is
 | 
						|
                _ ->
 | 
						|
                    when c is
 | 
						|
                        _ ->
 | 
						|
                            1
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_when() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            my_long_function_name = \x ->
 | 
						|
                when b is
 | 
						|
                    1 | 2 ->
 | 
						|
                        when c is
 | 
						|
                            6 | 7 ->
 | 
						|
                                8
 | 
						|
 | 
						|
                    3 | 4 ->
 | 
						|
                        5
 | 
						|
 | 
						|
            123
 | 
						|
        "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    #[ignore] // TODO: reformat when-in-function-body with extra newline
 | 
						|
    fn def_when_with_python_indentation() {
 | 
						|
        expr_formats_to(
 | 
						|
            // vvv Currently this input formats to _itself_ :( vvv
 | 
						|
            // Instead, if the body of the `when` is multiline (the overwhelmingly common case)
 | 
						|
            // we want to make sure the `when` is at the beginning of the line, inserting
 | 
						|
            // a newline if necessary.
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                myLongFunctionName = \x -> when b is
 | 
						|
                    1 | 2 ->
 | 
						|
                        when c is
 | 
						|
                            6 | 7 ->
 | 
						|
                                8
 | 
						|
 | 
						|
                    3 | 4 ->
 | 
						|
                        5
 | 
						|
 | 
						|
                123
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                myLongFunctionName = \x ->
 | 
						|
                    when b is
 | 
						|
                        1 | 2 ->
 | 
						|
                            when c is
 | 
						|
                                6 | 7 ->
 | 
						|
                                    8
 | 
						|
 | 
						|
                        3 | 4 ->
 | 
						|
                            5
 | 
						|
 | 
						|
                123
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_alternatives_1() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when b is
 | 
						|
                1 | 2 ->
 | 
						|
                    when c is
 | 
						|
                        6 | 7 ->
 | 
						|
                            8
 | 
						|
 | 
						|
                3 | 4 ->
 | 
						|
                    5
 | 
						|
        "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_alternatives_2() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when b is
 | 
						|
                # a comment here
 | 
						|
                1 | 2 ->
 | 
						|
                    # a comment there
 | 
						|
                    1
 | 
						|
        "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_alternatives_3() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is
 | 
						|
            1   |   2 |3 ->
 | 
						|
 | 
						|
                    1
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is
 | 
						|
                1 | 2 | 3 ->
 | 
						|
                    1
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_alternatives_4() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is
 | 
						|
                1   |   2 |
 | 
						|
                    3
 | 
						|
                ->
 | 
						|
 | 
						|
                        4
 | 
						|
                5   |   6 | 7 ->
 | 
						|
 | 
						|
                        8
 | 
						|
                9
 | 
						|
                 | 10 -> 11
 | 
						|
 | 
						|
                12 | 13 ->
 | 
						|
                  when c is
 | 
						|
                    14 | 15 -> 16
 | 
						|
                    17
 | 
						|
                     |  18 -> 19
 | 
						|
                20 -> 21
 | 
						|
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is
 | 
						|
                1
 | 
						|
                | 2
 | 
						|
                | 3 ->
 | 
						|
                    4
 | 
						|
 | 
						|
                5 | 6 | 7 ->
 | 
						|
                    8
 | 
						|
 | 
						|
                9
 | 
						|
                | 10 -> 11
 | 
						|
 | 
						|
                12 | 13 ->
 | 
						|
                    when c is
 | 
						|
                        14 | 15 -> 16
 | 
						|
                        17
 | 
						|
                        | 18 -> 19
 | 
						|
 | 
						|
                20 -> 21
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    #[ignore]
 | 
						|
    fn with_multiline_pattern_indentation() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is   3->4
 | 
						|
                        9
 | 
						|
                         |8->9
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            when b is
 | 
						|
                3 -> 4
 | 
						|
                9
 | 
						|
                | 8 -> 9
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_when_condition_1() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when
 | 
						|
                complexFunction a b c
 | 
						|
            is
 | 
						|
                1 ->
 | 
						|
                    Nothing
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    Just True
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_when_condition_2() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when
 | 
						|
                # this is quite complicated
 | 
						|
                complexFunction a b c
 | 
						|
                # Watch out
 | 
						|
            is
 | 
						|
                Complex x y ->
 | 
						|
                    simplify x y
 | 
						|
 | 
						|
                Simple z ->
 | 
						|
                    z
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_when_condition_3() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 2
 | 
						|
            y = 3
 | 
						|
 | 
						|
            when 1
 | 
						|
                + 1 is
 | 
						|
                2 ->
 | 
						|
                    x
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    y
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 2
 | 
						|
            y = 3
 | 
						|
 | 
						|
            when
 | 
						|
                1
 | 
						|
                + 1
 | 
						|
            is
 | 
						|
                2 ->
 | 
						|
                    x
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    y
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_when_condition_4() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 2
 | 
						|
            y = 3
 | 
						|
 | 
						|
            when 2
 | 
						|
                + 2
 | 
						|
            is
 | 
						|
                4 ->
 | 
						|
                    x
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    y
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 2
 | 
						|
            y = 3
 | 
						|
 | 
						|
            when
 | 
						|
                2
 | 
						|
                + 2
 | 
						|
            is
 | 
						|
                4 ->
 | 
						|
                    x
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    y
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_when_branch() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            when x is
 | 
						|
                Foo -> bar
 | 
						|
                    "arg1" "arg2"
 | 
						|
                Bar -> 2
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            when x is
 | 
						|
                Foo ->
 | 
						|
                    bar
 | 
						|
                        "arg1"
 | 
						|
                        "arg2"
 | 
						|
 | 
						|
                Bar -> 2
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_when_patterns() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when x is
 | 
						|
                Foo -> 1
 | 
						|
                Bar -> 2
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when x is
 | 
						|
                Foo -> 1
 | 
						|
                Bar ->
 | 
						|
                    2
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when x is
 | 
						|
                    Foo -> 1
 | 
						|
 | 
						|
                    Bar ->
 | 
						|
                        2
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when x is
 | 
						|
                    Foo -> 1
 | 
						|
                    Bar ->
 | 
						|
                        2
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when x is
 | 
						|
                    Foo -> 1
 | 
						|
 | 
						|
                    Bar -> 2
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when x is
 | 
						|
                    Foo -> 1
 | 
						|
                    Bar -> 2
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_with_single_quote_char() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                when x is
 | 
						|
                    '0' -> 0
 | 
						|
                    '1' -> 1
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // NEWLINES
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiple_blank_lines_collapse_to_one() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 5
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                y = 10
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x = 5
 | 
						|
 | 
						|
                y = 10
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn def_returning_closure() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f = \x -> x
 | 
						|
            g = \x -> x
 | 
						|
 | 
						|
            \x ->
 | 
						|
                a = f x
 | 
						|
                b = f x
 | 
						|
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn inner_def_with_triple_newline_before() {
 | 
						|
        // The triple newline used to cause the code in add_spaces to not indent the next line,
 | 
						|
        // which of course is not the same tree (and nor does it parse)
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                \x ->
 | 
						|
                    m = 2
 | 
						|
 | 
						|
 | 
						|
                    m1 = insert m n powerOf10
 | 
						|
 | 
						|
                    42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                \x ->
 | 
						|
                    m = 2
 | 
						|
 | 
						|
                    m1 = insert m n powerOf10
 | 
						|
 | 
						|
                    42
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_guard() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when maybeScore is
 | 
						|
                Just score if score > 21 ->
 | 
						|
                    win
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    nextRound
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn when_guard_using_function() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when authenticationResponse is
 | 
						|
                Ok user if hasPermission user ->
 | 
						|
                    loadPage route user
 | 
						|
 | 
						|
                Ok user ->
 | 
						|
                    PageNotFound
 | 
						|
 | 
						|
                Err _ ->
 | 
						|
                    ErrorPage
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // ACCESSOR
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn accessor() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            .id
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            user.name
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            (getUser userId users).name
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // PRECEDENCE CONFLICT
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn precedence_conflict() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if True == False == True then
 | 
						|
                False
 | 
						|
            else
 | 
						|
                True
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_precedence_conflict_1() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            if True
 | 
						|
                == False == True
 | 
						|
            then
 | 
						|
                False
 | 
						|
            else
 | 
						|
                True
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            if
 | 
						|
                True
 | 
						|
                == False
 | 
						|
                == True
 | 
						|
            then
 | 
						|
                False
 | 
						|
            else
 | 
						|
                True
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_precedence_conflict_2() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            if False
 | 
						|
                == False == False then
 | 
						|
                "true"
 | 
						|
            else
 | 
						|
                "false"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            if
 | 
						|
                False
 | 
						|
                == False
 | 
						|
                == False
 | 
						|
            then
 | 
						|
                "true"
 | 
						|
            else
 | 
						|
                "false"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn precedence_conflict_functions() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when f x == g y == h z is
 | 
						|
                True ->
 | 
						|
                    Ok 1
 | 
						|
 | 
						|
                False ->
 | 
						|
                    Err 2
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn binop_parens() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            if 4 == (6 ^ 6 ^ 7 ^ 8) then
 | 
						|
                "Hard to believe"
 | 
						|
            else
 | 
						|
                "Naturally"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            if 5 == 1 ^ 1 ^ 1 ^ 1 then
 | 
						|
                "Not buying it"
 | 
						|
            else
 | 
						|
                "True"
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            if (1 == 1)
 | 
						|
                && (2 == 1) && (3 == 2) then
 | 
						|
                "true"
 | 
						|
            else
 | 
						|
                "false"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            if
 | 
						|
                (1 == 1)
 | 
						|
                && (2 == 1)
 | 
						|
                && (3 == 2)
 | 
						|
            then
 | 
						|
                "true"
 | 
						|
            else
 | 
						|
                "false"
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_binop_with_comments() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                + 1 # comment 1
 | 
						|
                - 1 # comment 2
 | 
						|
                * 1 # comment 3
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                + 1 # comment 1
 | 
						|
                - 1 # comment 2
 | 
						|
                * 1 # comment 3
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                + 1 # comment 1
 | 
						|
                * 1 # comment 2
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                + 1 # comment 1
 | 
						|
                * 1 # comment 2
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                + 1 # comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                + 1 # comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                * 1
 | 
						|
                + 1 # comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                * 1
 | 
						|
                + 1 # comment
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                - 1
 | 
						|
                * 1
 | 
						|
                + 1
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                - 1
 | 
						|
                * 1
 | 
						|
                + 1
 | 
						|
 | 
						|
            x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_binop_if_with_comments() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            if
 | 
						|
                x
 | 
						|
                + 1 # comment 1
 | 
						|
                > 0 # comment 2
 | 
						|
            then
 | 
						|
                y
 | 
						|
                * 2 # comment 3
 | 
						|
                < 1 # comment 4
 | 
						|
            else
 | 
						|
                42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_binop_when_with_comments() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            when
 | 
						|
                x
 | 
						|
                + 1 # comment 1
 | 
						|
                > 0 # comment 2
 | 
						|
            is
 | 
						|
                y ->
 | 
						|
                    3
 | 
						|
                    * 2 # comment 3
 | 
						|
                    < 1 # comment 4
 | 
						|
 | 
						|
                z ->
 | 
						|
                    4
 | 
						|
                        / 5  # comment 5
 | 
						|
                            < 1    # comment 6
 | 
						|
 | 
						|
                46 # first pattern comment
 | 
						|
                | 95 # alternative comment 1
 | 
						|
                | 126 # alternative comment 2
 | 
						|
                | 150 -> # This comment came after the ->
 | 
						|
                    # This comment is for the expr
 | 
						|
                        foo bar
 | 
						|
                            |> Result.withDefault "" # one last comment
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    42
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
            when
 | 
						|
                x
 | 
						|
                + 1 # comment 1
 | 
						|
                > 0 # comment 2
 | 
						|
            is
 | 
						|
                y ->
 | 
						|
                    3
 | 
						|
                    * 2 # comment 3
 | 
						|
                    < 1 # comment 4
 | 
						|
 | 
						|
                z ->
 | 
						|
                    4
 | 
						|
                    / 5 # comment 5
 | 
						|
                    < 1 # comment 6
 | 
						|
 | 
						|
                46 # first pattern comment
 | 
						|
                | 95 # alternative comment 1
 | 
						|
                | 126 # alternative comment 2
 | 
						|
                | 150 -> # This comment came after the ->
 | 
						|
                    # This comment is for the expr
 | 
						|
                    foo bar
 | 
						|
                    |> Result.withDefault "" # one last comment
 | 
						|
 | 
						|
                _ ->
 | 
						|
                    42
 | 
						|
            "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn precedence_conflict_greater_than() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            3 > 4 > 10
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn precedence_conflict_greater_than_and_less_than() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            1 < 4 > 1
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn binop_if() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            5 * (if x > 0 then 1 else 2)
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // UNARY OP
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn unary_op() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                y = -4
 | 
						|
 | 
						|
                !x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn unary_call_parens() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                !(f 1)
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn unary_call_no_parens() {
 | 
						|
        // TIL: Negating a function "does what you might expect"... which is cool!
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                !f 1
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // BINARY OP
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn binary_op() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            1 == 1
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn binary_op_with_spaces() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                2   !=   3
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                2 != 3
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_binary_op_1() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            isLast
 | 
						|
            && isEmpty
 | 
						|
            && isLoaded
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_binary_op_2() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x = 1
 | 
						|
                < 2
 | 
						|
 | 
						|
            f x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            x =
 | 
						|
                1
 | 
						|
                < 2
 | 
						|
 | 
						|
            f x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_binary_op_with_comments() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                1
 | 
						|
                * 2
 | 
						|
                / 3
 | 
						|
                // 4
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                1
 | 
						|
                * 2
 | 
						|
                / 3
 | 
						|
                // 4
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn partial_multi_line_binary_op_1() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                2 % 3
 | 
						|
                    // 5
 | 
						|
                    + 7
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                2
 | 
						|
                % 3
 | 
						|
                // 5
 | 
						|
                + 7
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn partial_multi_line_binary_op_2() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                isGreenLight
 | 
						|
                    && isRedLight && isYellowLight
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                isGreenLight
 | 
						|
                && isRedLight
 | 
						|
                && isYellowLight
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn pipline_op_with_apply() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            output
 | 
						|
            |> List.set (offset + 0) b
 | 
						|
            |> List.set (offset + 1) a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn apply_lambda() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            List.map
 | 
						|
                xs
 | 
						|
                (\i ->
 | 
						|
                    i + length)
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn pipline_apply_lambda_1() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            shout
 | 
						|
            |> List.map
 | 
						|
                xs
 | 
						|
                (\i -> i)
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn pipline_apply_lambda_2() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            shout
 | 
						|
            |> List.map
 | 
						|
                xs
 | 
						|
                (\i -> i)
 | 
						|
            |> List.join
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comment_between_multiline_ann_args() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                blah :
 | 
						|
                    (Str -> Str)
 | 
						|
                    -> Str
 | 
						|
 | 
						|
                42
 | 
						|
            "
 | 
						|
        ))
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn pipeline_apply_lambda_multiline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                example = \model ->
 | 
						|
                    model
 | 
						|
                    |> withModel
 | 
						|
                        (\result ->
 | 
						|
                            when result is
 | 
						|
                                Err _ ->
 | 
						|
                                    Err {}
 | 
						|
 | 
						|
                                Ok val ->
 | 
						|
                                    Ok {}
 | 
						|
                        )
 | 
						|
 | 
						|
                example
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    example = \model ->
 | 
						|
                        model
 | 
						|
                            |> withModel
 | 
						|
                                (\result ->
 | 
						|
                                        when result is
 | 
						|
                                            Err _ ->
 | 
						|
                                                Err {}
 | 
						|
 | 
						|
                                            Ok val ->
 | 
						|
                                                Ok {}
 | 
						|
                                )
 | 
						|
 | 
						|
                    example
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    example = \model ->
 | 
						|
                        model
 | 
						|
                        |> withModel
 | 
						|
                            (\result ->
 | 
						|
                                when result is
 | 
						|
                                    Err _ ->
 | 
						|
                                        Err {}
 | 
						|
 | 
						|
                                    Ok val ->
 | 
						|
                                        Ok {}
 | 
						|
                            )
 | 
						|
 | 
						|
                    example
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn func_call_trailing_multiline_lambda() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                list = List.map [1, 2, 3] \x ->
 | 
						|
                    x + 1
 | 
						|
 | 
						|
                list
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // MODULES
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_module() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                module []"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn defs_with_trailing_comment() {
 | 
						|
        // TODO: make the formatter add a space between '42' and # below:
 | 
						|
        module_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            module []
 | 
						|
 | 
						|
            a = 42 # Yay greetings"
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            module []
 | 
						|
 | 
						|
            a = 42 # Yay greetings
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn module_exposing() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                module [Bar, Baz, a, b]"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn module_exposing_multiline() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                module [
 | 
						|
                    Stuff,
 | 
						|
                    Things,
 | 
						|
                    somethingElse,
 | 
						|
                ]
 | 
						|
 | 
						|
                import Blah
 | 
						|
                import Baz exposing [stuff, things]"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn old_style_app_header_is_upgraded() {
 | 
						|
        module_formats_to(
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                app \"test\"
 | 
						|
                    packages {
 | 
						|
                        pf: \"platform/main.roc\"
 | 
						|
                    }
 | 
						|
                    provides [main] to pf
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                app [main] {
 | 
						|
                    pf: platform \"platform/main.roc\",
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn old_style_package_header_is_upgraded() {
 | 
						|
        module_formats_to(
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                package \"csv\"
 | 
						|
                    exposes [Csv]
 | 
						|
                    packages {
 | 
						|
                        parser: \"parser/main.roc\"
 | 
						|
                    }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                package [Csv] {
 | 
						|
                    parser: \"parser/main.roc\",
 | 
						|
                }
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_app() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                app [main] { pf: platform "platform/main.roc" }"#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_platform() {
 | 
						|
        module_formats_same(
 | 
						|
            "platform \"folkertdev/foo\" \
 | 
						|
            requires { Model, Msg } { main : Task {} [] } \
 | 
						|
            exposes [] \
 | 
						|
            packages {} \
 | 
						|
            imports [] \
 | 
						|
            provides [mainForHost]",
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn module_defs_with_comments() {
 | 
						|
        module_formats_to(
 | 
						|
            &format!(
 | 
						|
                indoc!(
 | 
						|
                    r#"
 | 
						|
                    module []
 | 
						|
 | 
						|
                    # comment 1{space}
 | 
						|
                    def = "" # comment 2{space}
 | 
						|
                    # comment 3{space}
 | 
						|
                "#
 | 
						|
                ),
 | 
						|
                space = " "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    module []
 | 
						|
 | 
						|
                    # comment 1
 | 
						|
                    def = "" # comment 2
 | 
						|
                    # comment 3
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_tui_package_config() {
 | 
						|
        // At one point this failed to reformat.
 | 
						|
        module_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    platform "tui"
 | 
						|
                        requires { Model } { main : { init : ({} -> Model), update : (Model, Str -> Model), view : (Model -> Str) } }
 | 
						|
                        exposes []
 | 
						|
                        packages {}
 | 
						|
                        imports []
 | 
						|
                        provides [ main_for_host ]
 | 
						|
 | 
						|
                    main_for_host : { init : ({} -> Model) as Init, update : (Model, Str -> Model) as Update, view : (Model -> Str) as View }
 | 
						|
                    main_for_host = main
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    platform "tui"
 | 
						|
                        requires { Model } { main : { init : {} -> Model, update : Model, Str -> Model, view : Model -> Str } }
 | 
						|
                        exposes []
 | 
						|
                        packages {}
 | 
						|
                        imports []
 | 
						|
                        provides [main_for_host]
 | 
						|
 | 
						|
                    main_for_host : { init : ({} -> Model) as Init, update : (Model, Str -> Model) as Update, view : (Model -> Str) as View }
 | 
						|
                    main_for_host = main
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_hosted() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                hosted Foo exposes [] imports []"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_hosted() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                hosted Foo
 | 
						|
                    exposes [
 | 
						|
                        Stuff,
 | 
						|
                        Things,
 | 
						|
                        somethingElse,
 | 
						|
                    ]
 | 
						|
                    imports [
 | 
						|
                        Blah,
 | 
						|
                        Baz.{ stuff, things },
 | 
						|
                    ]"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    /// Annotations and aliases
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn list_alias() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            ConsList a : [Cons a (ConsList a), Nil]
 | 
						|
 | 
						|
            f : ConsList a -> ConsList a
 | 
						|
            f = \_ -> Nil
 | 
						|
 | 
						|
            f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn wildcard() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : List *
 | 
						|
            f = []
 | 
						|
 | 
						|
            a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn identity() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : a -> a
 | 
						|
            f = []
 | 
						|
 | 
						|
            a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn weird_triple_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _""""w"""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _
 | 
						|
                    """
 | 
						|
                    "w
 | 
						|
                    """
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_tag_union_annotation_no_comments() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            b : [
 | 
						|
                True,
 | 
						|
                False,
 | 
						|
            ]
 | 
						|
 | 
						|
            b
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            b :
 | 
						|
                [True, False]
 | 
						|
 | 
						|
            b
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                b :
 | 
						|
                    [
 | 
						|
                        True,
 | 
						|
                        False,
 | 
						|
                    ]
 | 
						|
 | 
						|
                b
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                b : [
 | 
						|
                    True,
 | 
						|
                    False,
 | 
						|
                ]
 | 
						|
 | 
						|
                b
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                b : [
 | 
						|
                        True,
 | 
						|
                        False,
 | 
						|
                    ]
 | 
						|
 | 
						|
                b
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                b : [
 | 
						|
                    True,
 | 
						|
                    False,
 | 
						|
                ]
 | 
						|
 | 
						|
                b
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_tag_union_annotation_beginning_on_same_line() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            Expr : [
 | 
						|
                Add Expr Expr,
 | 
						|
                Mul Expr Expr,
 | 
						|
                Val I64,
 | 
						|
                Var I64,
 | 
						|
            ]
 | 
						|
 | 
						|
            Expr"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_tag_union_annotation_with_final_comment() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            b :
 | 
						|
                [
 | 
						|
                    True,
 | 
						|
                    # comment 1
 | 
						|
                    False # comment 2
 | 
						|
                    ,
 | 
						|
                    # comment 3
 | 
						|
                ]
 | 
						|
 | 
						|
            b
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                b : [
 | 
						|
                    True,
 | 
						|
                    # comment 1
 | 
						|
                    False, # comment 2
 | 
						|
                    # comment 3
 | 
						|
                ]
 | 
						|
 | 
						|
                b
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn tag_union() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : [True, False] -> [True, False]
 | 
						|
            f = \x -> x
 | 
						|
 | 
						|
            a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // TODO: the current formatting seems a bit odd for multiline function annotations
 | 
						|
    // (beside weird indentation, note the trailing space after the "->")
 | 
						|
    // #[test]
 | 
						|
    // fn multiline_tag_union_function_annotation() {
 | 
						|
    //     expr_formats_same(indoc!(
 | 
						|
    //         r"
 | 
						|
    //         f :
 | 
						|
    //             [
 | 
						|
    //                 True,
 | 
						|
    //                 False,
 | 
						|
    //             ] ->
 | 
						|
    //             [
 | 
						|
    //                 True,
 | 
						|
    //                 False,
 | 
						|
    //             ]
 | 
						|
    //         f = \x -> x
 | 
						|
 | 
						|
    //         a
 | 
						|
    //         "
 | 
						|
    //     ));
 | 
						|
    // }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn recursive_tag_union() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : [Cons a (ConsList a), Nil] as ConsList a -> [Just a, Nothing]
 | 
						|
            f = \list ->
 | 
						|
                when list is
 | 
						|
                    Nil ->
 | 
						|
                        Nothing
 | 
						|
 | 
						|
                    Cons first _ ->
 | 
						|
                        Just first
 | 
						|
 | 
						|
            f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn function_application_package_type() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            main : Task.Task {} []
 | 
						|
            main = 42
 | 
						|
 | 
						|
            main
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_type() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : { foo : Int * }
 | 
						|
            f = { foo: 1000 }
 | 
						|
 | 
						|
            a
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_pattern_with_apply_guard() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when { x: 1 } is
 | 
						|
                { x: Just 4 } ->
 | 
						|
                    4
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn record_pattern_with_record_guard() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when { x: 1 } is
 | 
						|
                { x: { x: True } } ->
 | 
						|
                    4
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn body_starts_with_spaces_multiline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            y =
 | 
						|
                Foo
 | 
						|
                    1
 | 
						|
                    2
 | 
						|
 | 
						|
            y
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn backpassing_simple() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                get_char = \ctx ->
 | 
						|
                    x <- Task.await (get_char_scope scope)
 | 
						|
                    42
 | 
						|
 | 
						|
                42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn backpassing_apply_tag() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                get_char = \ctx ->
 | 
						|
                    (T val new_scope) <- Task.await (get_char_scope scope)
 | 
						|
                    42
 | 
						|
 | 
						|
                42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn backpassing_parens_body() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            Task.fromResult
 | 
						|
                (
 | 
						|
                    b <- binaryOp ctx
 | 
						|
                    if a == b then
 | 
						|
                        -1
 | 
						|
                    else
 | 
						|
                        0
 | 
						|
                )
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    Task.fromResult
 | 
						|
                        (b <- binaryOp ctx
 | 
						|
                            if a == b then
 | 
						|
                                -1
 | 
						|
                            else
 | 
						|
                                0
 | 
						|
                            )
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    Task.fromResult
 | 
						|
                        (
 | 
						|
                            b <- binaryOp ctx
 | 
						|
                            if a == b then
 | 
						|
                                -1
 | 
						|
                            else
 | 
						|
                                0
 | 
						|
                        )
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    Task.fromResult
 | 
						|
                        (b <- binaryOp ctx
 | 
						|
                            if a == b then
 | 
						|
                                -1
 | 
						|
                            else
 | 
						|
                                0)
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    Task.fromResult
 | 
						|
                        (
 | 
						|
                            b <- binaryOp ctx
 | 
						|
                            if a == b then
 | 
						|
                                -1
 | 
						|
                            else
 | 
						|
                                0
 | 
						|
                        )
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn backpassing_body_on_newline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                get_char = \ctx ->
 | 
						|
                    x <-
 | 
						|
                        Task.await (get_char_scope scope)
 | 
						|
                    42
 | 
						|
 | 
						|
                42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_higher_order_function() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            foo :
 | 
						|
                (Str -> Bool)
 | 
						|
                -> Bool
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            foo :
 | 
						|
                (Str -> Bool),
 | 
						|
                Str
 | 
						|
                -> Bool
 | 
						|
            foo = \bar, baz ->
 | 
						|
                42
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                foo :
 | 
						|
                    (Str -> Bool) -> Bool
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                foo :
 | 
						|
                    (Str -> Bool), Str -> Bool
 | 
						|
                foo = \bar, baz ->
 | 
						|
                    42
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                foo :
 | 
						|
                    (Str -> Bool), Str -> Bool # comment
 | 
						|
                foo = \bar, baz ->
 | 
						|
                    42
 | 
						|
 | 
						|
                42
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multiline_opaque_tag_union() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := [
 | 
						|
                B,
 | 
						|
                C,
 | 
						|
            ]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn opaque_implements_clause() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := U8 implements [Eq, Hash]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                A :=
 | 
						|
                    U8
 | 
						|
                    implements [Eq, Hash]
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := a where a implements Hash implements [ Eq, Hash ]
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := a where a implements Hash
 | 
						|
                    implements [Eq, Hash]
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := U8 implements []
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := U8 implements []
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comma_prefixed_indented_record() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            Model position :
 | 
						|
                { evaluated : Set position
 | 
						|
                , openSet : Set position
 | 
						|
                , costs : Dict.Dict position F64
 | 
						|
                , cameFrom : Dict.Dict position position
 | 
						|
                }
 | 
						|
 | 
						|
 | 
						|
            a
 | 
						|
            ",
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
            Model position : {
 | 
						|
                evaluated : Set position,
 | 
						|
                openSet : Set position,
 | 
						|
                costs : Dict.Dict position F64,
 | 
						|
                cameFrom : Dict.Dict position position,
 | 
						|
            }
 | 
						|
 | 
						|
            a
 | 
						|
            ",
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn opaque_implements_with_impls() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := U8 implements [Eq { eq }, Hash { hash }]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := U8 implements [Eq { eq, eq1 }]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := U8 implements [Eq {   eq,     eq1   }]
 | 
						|
                A := U8 implements [Eq {
 | 
						|
                                    eq,
 | 
						|
                                    eq1
 | 
						|
                                }]
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                A := U8 implements [Eq { eq, eq1 }]
 | 
						|
                A := U8 implements [
 | 
						|
                        Eq {
 | 
						|
                            eq,
 | 
						|
                            eq1,
 | 
						|
                        },
 | 
						|
                    ]
 | 
						|
 | 
						|
                0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := a where a implements Other
 | 
						|
                implements [Eq { eq }, Hash { hash }]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            A := U8 implements [Eq {}]
 | 
						|
 | 
						|
            0
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comments_in_multiline_tag_union_annotation() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    UnionAnn : [
 | 
						|
                        Foo, # comment 1
 | 
						|
                        Bar, # comment 2
 | 
						|
                        Baz, # comment 3
 | 
						|
                             # comment 4 line 1
 | 
						|
                             # comment 4 line 2
 | 
						|
                    ]
 | 
						|
 | 
						|
                    0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    UnionAnn : [
 | 
						|
                        Foo, # comment 1
 | 
						|
                        Bar, # comment 2
 | 
						|
                        Baz, # comment 3
 | 
						|
                        # comment 4 line 1
 | 
						|
                        # comment 4 line 2
 | 
						|
                    ]
 | 
						|
 | 
						|
                    0
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn test_where_after() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                Dict k v := {
 | 
						|
                    metadata : List I8,
 | 
						|
                    dataIndices : List U64,
 | 
						|
                    data : List (T k v),
 | 
						|
                    size : U64,
 | 
						|
                } where k implements Hash & Eq
 | 
						|
 | 
						|
                a
 | 
						|
                "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    /// Test that everything under examples/ is formatted correctly
 | 
						|
    /// If this test fails on your diff, it probably means you need to re-format the examples.
 | 
						|
    /// Try this:
 | 
						|
    /// `cargo run -- format $(find examples -name \*.roc)`
 | 
						|
    fn test_fmt_examples() {
 | 
						|
        let mut count = 0;
 | 
						|
        let mut root = workspace_root();
 | 
						|
        root.push("examples");
 | 
						|
        for entry in walkdir::WalkDir::new(&root) {
 | 
						|
            let entry = entry.unwrap();
 | 
						|
            let path = entry.path();
 | 
						|
            if path.extension() == Some(std::ffi::OsStr::new("roc")) {
 | 
						|
                count += 1;
 | 
						|
                let src = std::fs::read_to_string(path).unwrap();
 | 
						|
                println!("Now trying to format {}", path.display());
 | 
						|
                module_formats_same(&src);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        assert!(
 | 
						|
            count > 0,
 | 
						|
            "Expecting to find at least 1 .roc file to format under {}",
 | 
						|
            root.display()
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    /// Test that builtins are formatted correctly
 | 
						|
    /// If this test fails on your diff, it probably means you need to re-format a builtin.
 | 
						|
    /// Try this:
 | 
						|
    /// `cargo run -- format $(find crates/compiler/builtins/roc -name \*.roc)`
 | 
						|
    fn test_fmt_builtins() {
 | 
						|
        let mut count = 0;
 | 
						|
        let builtins_path = workspace_root()
 | 
						|
            .join("crates")
 | 
						|
            .join("compiler")
 | 
						|
            .join("builtins")
 | 
						|
            .join("roc");
 | 
						|
 | 
						|
        for entry in walkdir::WalkDir::new(&builtins_path) {
 | 
						|
            let entry = entry.unwrap();
 | 
						|
            let path = entry.path();
 | 
						|
            if path.extension() == Some(std::ffi::OsStr::new("roc")) {
 | 
						|
                count += 1;
 | 
						|
                let src = std::fs::read_to_string(path).unwrap();
 | 
						|
                println!("Now trying to format {}", path.display());
 | 
						|
                module_formats_same(&src);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        assert!(
 | 
						|
            count > 0,
 | 
						|
            "Expecting to find at least 1 .roc file to format under {}",
 | 
						|
            builtins_path.display()
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn expect_single_line() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
 | 
						|
            expect x == y
 | 
						|
 | 
						|
            expect y == z
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                module []
 | 
						|
 | 
						|
                expect x == y
 | 
						|
 | 
						|
                expect y == z
 | 
						|
 | 
						|
                foo = bar
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn expect_multiline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            x = 5
 | 
						|
 | 
						|
            expect
 | 
						|
                foo bar
 | 
						|
                |> baz
 | 
						|
 | 
						|
            42
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                module []
 | 
						|
 | 
						|
                expect
 | 
						|
                    foo bar
 | 
						|
                    |> baz
 | 
						|
 | 
						|
                expect
 | 
						|
                    blah
 | 
						|
                        etc
 | 
						|
 | 
						|
                foo = bar
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn single_line_string_literal_in_pattern() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            when foo is
 | 
						|
                "abc" -> ""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_string_literal_in_pattern() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            when foo is
 | 
						|
                """
 | 
						|
                abc
 | 
						|
                def
 | 
						|
                """ -> ""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn multi_line_string_literal_that_can_be_single_line_in_pattern() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                when foo is
 | 
						|
                    """
 | 
						|
                    abc
 | 
						|
                    """ -> ""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                when foo is
 | 
						|
                    "abc" -> ""
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_chars() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            ' '
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            '\n'
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_char_pattern() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when x is
 | 
						|
                ' ' -> x
 | 
						|
                '\n' -> x
 | 
						|
                '\t' -> x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_nested_pipeline() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            (a |> b) |> c
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            a |> b |> c
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn ability_member_doc_comments() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            module []
 | 
						|
 | 
						|
            A implements
 | 
						|
                ## This is member ab
 | 
						|
                ab : a -> a where a implements A
 | 
						|
 | 
						|
                ## This is member de
 | 
						|
                de : a -> a where a implements A
 | 
						|
 | 
						|
            f = g
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn leading_comments_preserved() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            # hello world
 | 
						|
            module []
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            # hello world
 | 
						|
            app [] { pf: platform "./platform" }
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            # hello world
 | 
						|
            platform "hello-world"
 | 
						|
                requires {} { main : Str }
 | 
						|
                exposes []
 | 
						|
                packages {}
 | 
						|
                imports []
 | 
						|
                provides [mainForHost]
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn comments_before_exposes_preserved() {
 | 
						|
        module_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            module
 | 
						|
                # comment
 | 
						|
                [a, b]
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn clauses_with_multiple_abilities() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            f : {} -> a where a implements Eq & Hash & Decode
 | 
						|
 | 
						|
            f
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                f : {} -> a where a implements Eq & Hash & Decode,
 | 
						|
                              b implements Eq & Hash
 | 
						|
 | 
						|
                f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                // TODO: ideally, this would look a bit nicer - consider
 | 
						|
                // f : {} -> a
 | 
						|
                //   where a implements Eq & Hash & Decode,
 | 
						|
                //     b implements Eq & Hash
 | 
						|
                r"
 | 
						|
                f : {} -> a where a implements Eq & Hash & Decode, b implements Eq & Hash
 | 
						|
 | 
						|
                f
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_list_patterns() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
            when [] is
 | 
						|
                [] -> []
 | 
						|
            "
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [  ] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [ x,  ..  ,    A  5   6,  .. ] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [x, .., A 5 6, ..] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [ x, 4, 5 ] -> []
 | 
						|
                    [ ..,   5 ] -> []
 | 
						|
                    [ x,   .. ] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when [] is
 | 
						|
                    [x, 4, 5] -> []
 | 
						|
                    [.., 5] -> []
 | 
						|
                    [x, ..] -> []
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_crash() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            _ = crash
 | 
						|
            _ = crash ""
 | 
						|
 | 
						|
            crash "" ""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _ = crash
 | 
						|
                _ = crash    ""
 | 
						|
                _ = crash   ""   ""
 | 
						|
                try
 | 
						|
                    foo
 | 
						|
                    (\_ ->   crash "")
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _ = crash
 | 
						|
                _ = crash ""
 | 
						|
                _ = crash "" ""
 | 
						|
                try
 | 
						|
                    foo
 | 
						|
                    (\_ -> crash "")
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn format_try() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
            _ = crash
 | 
						|
            _ = crash ""
 | 
						|
 | 
						|
            crash "" ""
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _ = crash
 | 
						|
                _ = crash    ""
 | 
						|
                _ = crash   ""   ""
 | 
						|
                try
 | 
						|
                    foo
 | 
						|
                    (\_ ->   crash "")
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                _ = crash
 | 
						|
                _ = crash ""
 | 
						|
                _ = crash "" ""
 | 
						|
                try
 | 
						|
                    foo
 | 
						|
                    (\_ -> crash "")
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn issue_6197() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when l1 is
 | 
						|
                    [
 | 
						|
                    ..
 | 
						|
                    as
 | 
						|
                    rest
 | 
						|
                    ]
 | 
						|
                    as
 | 
						|
                    l2
 | 
						|
                    ->
 | 
						|
                        f rest
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when l1 is
 | 
						|
                    [.. as rest] as l2 ->
 | 
						|
                        f rest
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn issue_6215() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when list is
 | 
						|
                    [first as last]
 | 
						|
                    | [first, last]   ->
 | 
						|
                        first
 | 
						|
                    _->Not
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                when list is
 | 
						|
                    [first as last]
 | 
						|
                    | [first, last] ->
 | 
						|
                        first
 | 
						|
 | 
						|
                    _ -> Not
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : i32
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : i32 # comment
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body_comments() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : i32
 | 
						|
                # comment
 | 
						|
                # comment 2
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body_comments_without_newlines() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    x : i32
 | 
						|
 | 
						|
                    # comment
 | 
						|
 | 
						|
                    # comment 2
 | 
						|
 | 
						|
                    x = 1
 | 
						|
                    x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                    x : i32
 | 
						|
                    # comment
 | 
						|
                    # comment 2
 | 
						|
                    x = 1
 | 
						|
                    x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body_blank_comment() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r"
 | 
						|
                x : i32
 | 
						|
                #
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_annotated_body_without_newlines() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x : i32
 | 
						|
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r"
 | 
						|
                x : i32
 | 
						|
                x = 1
 | 
						|
                x
 | 
						|
            "
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn keep_explicit_blank_chars() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            r#"
 | 
						|
                x = "a\u(200a)b\u(200b)c\u(200c)d\u(feff)e"
 | 
						|
                x
 | 
						|
            "#
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn make_blank_chars_explicit() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                    x = \"a\u{200A}b\u{200B}c\u{200C}d\u{FEFF}e\"
 | 
						|
                    x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    x = "a\u(200a)b\u(200b)c\u(200c)d\u(feff)e"
 | 
						|
                    x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn make_blank_chars_explicit_when_interpolating() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                    x = \"foo:\u{200B} $(bar).\"
 | 
						|
                    x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    x = "foo:\u(200b) $(bar)."
 | 
						|
                    x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn make_blank_chars_explicit_in_multiline_string() {
 | 
						|
        expr_formats_to(
 | 
						|
            indoc!(
 | 
						|
                "
 | 
						|
                    x =
 | 
						|
                        \"\"\"
 | 
						|
                        foo:\u{200B} $(bar).
 | 
						|
                        \"\"\"
 | 
						|
                    x
 | 
						|
                "
 | 
						|
            ),
 | 
						|
            indoc!(
 | 
						|
                r#"
 | 
						|
                    x =
 | 
						|
                        """
 | 
						|
                        foo:\u(200b) $(bar).
 | 
						|
                        """
 | 
						|
                    x
 | 
						|
                "#
 | 
						|
            ),
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    #[test]
 | 
						|
    fn preserve_multiline_string_trailing_whitespace() {
 | 
						|
        expr_formats_same(indoc!(
 | 
						|
            "x =\n    \"\"\"\n    foo\n    bar                \n    baz\n    \"\"\"\nx"
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    // this is a parse error atm
 | 
						|
    //    #[test]
 | 
						|
    //    fn multiline_apply() {
 | 
						|
    //        expr_formats_same(indoc!(
 | 
						|
    //            r"
 | 
						|
    //            f :
 | 
						|
    //                Result a
 | 
						|
    //                    { x : Int *
 | 
						|
    //                    , y : Float
 | 
						|
    //                    }
 | 
						|
    //                    c
 | 
						|
    //                -> Int *
 | 
						|
    //            f =
 | 
						|
    //                \_ -> 4
 | 
						|
    //            "
 | 
						|
    //        ));
 | 
						|
    //    }
 | 
						|
}
 |