diff --git a/crates/aiken-lang/src/parser/utils.rs b/crates/aiken-lang/src/parser/utils.rs
index f45a639e..7db0eb8c 100644
--- a/crates/aiken-lang/src/parser/utils.rs
+++ b/crates/aiken-lang/src/parser/utils.rs
@@ -97,3 +97,24 @@ macro_rules! assert_definition {
});
};
}
+
+#[macro_export]
+macro_rules! assert_format {
+ ($code:expr) => {
+ let src = indoc::indoc! { $code };
+
+ let (module, extra) =
+ $crate::parser::module(src, $crate::ast::ModuleKind::Lib).expect("Failed to parse code");
+
+ let mut out = String::new();
+ $crate::format::pretty(&mut out, module, extra, &src);
+
+ insta::with_settings!({
+ description => concat!("Code:\n\n", indoc::indoc! { $code }),
+ prepend_module_to_snapshot => false,
+ omit_expression => true
+ }, {
+ insta::assert_snapshot!(out);
+ });
+ };
+}
diff --git a/crates/aiken-lang/src/tests/format.rs b/crates/aiken-lang/src/tests/format.rs
index bea5d2e8..31e05f31 100644
--- a/crates/aiken-lang/src/tests/format.rs
+++ b/crates/aiken-lang/src/tests/format.rs
@@ -1,59 +1,24 @@
-use crate::{ast::ModuleKind, format, parser};
-use indoc::indoc;
-use pretty_assertions::assert_eq;
-
-fn assert_fmt(src: &str, expected: &str) {
- let (module, extra) = parser::module(src, ModuleKind::Lib).unwrap();
- let mut out = String::new();
- format::pretty(&mut out, module, extra, src);
-
- // Output is what we expect
- assert_eq!(out, expected);
-
- // Formatting is idempotent
- let (module2, extra2) = parser::module(&out, ModuleKind::Lib).unwrap();
- let mut out2 = String::new();
- format::pretty(&mut out2, module2, extra2, &out);
- assert_eq!(out, out2, "formatting isn't idempotent");
-}
+use crate::assert_format;
#[test]
-fn comment_at_end_of_file() {
- let input = indoc! { r#"
+fn test_format_comment_at_end_of_file() {
+ assert_format!(r#"
type Foo =
Int
- //"#};
-
- let output = indoc! { r#"
- type Foo =
- Int
- //
- "#};
-
- assert_fmt(input, output);
+ //"#);
}
#[test]
-fn module_select_record() {
- let input = indoc! { r#"
- fn smth() {
- let a = foo.Foo { bar: 1 }
- }
- "#};
-
- let output = indoc! { r#"
- fn smth() {
- let a = foo.Foo { bar: 1 }
- }
- "#};
-
- assert_fmt(input, output);
+fn test_format_simple_module() {
+ assert_format!(r#"
+ fn smth() { let a = foo.Foo { bar: 1 } }
+ "#);
}
#[test]
fn test_format_if() {
- let src = indoc! {r#"
+ assert_format!(r#"
pub fn foo(a) {
if a { 14 } else { 42 }
}
@@ -61,37 +26,12 @@ fn test_format_if() {
pub fn bar(xs) {
list.map(xs, fn (x) { if x > 0 { "foo" } else { "bar" } })
}
- "#};
-
- let expected = indoc! {r#"
- pub fn foo(a) {
- if a {
- 14
- } else {
- 42
- }
- }
-
- pub fn bar(xs) {
- list.map(
- xs,
- fn(x) {
- if x > 0 {
- "foo"
- } else {
- "bar"
- }
- },
- )
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_validator() {
- let src = indoc! {r#"
+ assert_format!(r#"
validator ( ) {
// What is the purpose of life
@@ -109,34 +49,12 @@ fn test_format_validator() {
// I am lost
}
- "#};
-
- let expected = indoc! {r#"
- validator {
- // What is the purpose of life
-
- fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
- True
- }
- }
-
- // What?
- validator {
- /// Some documentation for foo
- fn foo() {
- Void
- }
-
- // I am lost
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_double_validator() {
- let src = indoc! {r#"
+ assert_format!(r#"
validator ( param1 : ByteArray ) {
fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
True
@@ -144,27 +62,12 @@ fn test_format_double_validator() {
/// This is bar
fn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True }
}
- "#};
-
- let expected = indoc! {r#"
- validator(param1: ByteArray) {
- fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
- True
- }
-
- /// This is bar
- fn bar(r: Redeemer, ctx: ScriptContext) -> Bool {
- True
- }
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_when() {
- let src = indoc! {r#"
+ assert_format!(r#"
pub fn foo( a) {
when a is{
True -> {
@@ -180,55 +83,25 @@ fn test_format_when() {
}
}
- "#};
-
- let expected = indoc! {r#"
- pub fn foo(a) {
- when a is {
- True -> {
- bar()
-
- 14
- }
-
- False -> 42
- }
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_nested_if() {
- let src = indoc! {r#"
+ assert_format!(r#"
pub fn foo(n) {
if n > 0 {
- if n > 1 {
- if n > 2 {
- "foo"
- } else {
- "foo"
- }
- } else {
- "bar"
- }
+ if n > 1 { if n > 2 { "foo" } else { "foo" } } else { "bar" }
} else {
- if n < -1 {
- "baz"
- } else {
- "biz"
- }
+ if n < -1 { "baz" } else { "biz" }
}
}
- "#};
-
- assert_fmt(src, src)
+ "#);
}
#[test]
fn test_format_nested_when_if() {
- let src = indoc! {r#"
+ assert_format!(r#"
pub fn drop(xs: List, n: Int) -> List {
if n <= 0 {
xs
@@ -241,28 +114,12 @@ fn test_format_nested_when_if() {
}
}
}
- "#};
-
- let expected = indoc! {r#"
- pub fn drop(xs: List, n: Int) -> List {
- if n <= 0 {
- xs
- } else {
- when xs is {
- [] ->
- []
- [_x, ..rest] -> drop(rest, n - 1)
- }
- }
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_nested_when() {
- let src = indoc! {r#"
+ assert_format!(r#"
fn foo() {
when a is {
None -> "foo"
@@ -275,31 +132,12 @@ fn test_format_nested_when() {
}
}
}
- "#};
-
- let expected = indoc! {r#"
- fn foo() {
- when a is {
- None -> "foo"
- Some(b) ->
- when b is {
- None -> "foo"
- Some(c) ->
- when c is {
- None -> "foo"
- Some(_) -> "foo"
- }
- }
- }
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
fn test_format_else_if() {
- let src = indoc! {r#"
+ assert_format!(r#"
pub fn foo(xs: List, n: Int) -> List {
if n <= 0 {
xs
@@ -309,14 +147,14 @@ fn test_format_else_if() {
xs
}
}
- "#};
-
- assert_fmt(src, src)
+ "#);
}
#[test]
fn test_format_imports() {
- let src = indoc! {r#"
+ // TODO: Fix this case, this is behaving weirdly, not keeping the order for the comments and
+ // imports.
+ assert_format!(r#"
use aiken/list
// foo
use aiken/bytearray
@@ -324,41 +162,21 @@ fn test_format_imports() {
// bar
use aiken/transaction
use aiken/transaction/value
- "#};
-
- let expected = indoc! {r#"
- // foo
- use aiken/bytearray
- use aiken/list
- // bar
- use aiken/transaction
- use aiken/transaction/certificate
- use aiken/transaction/value
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
-fn test_negate() {
- let src = indoc! {r#"
+fn test_format_negate() {
+ assert_format!(r#"
fn foo() {
- 42
}
- "#};
-
- let expected = indoc! {r#"
- fn foo() {
- -42
- }
- "#};
-
- assert_fmt(src, expected)
+ "#);
}
#[test]
-fn test_block_arithmetic_expr() {
- let src = indoc! {r#"
+fn test_format_block_arithmetic_expr() {
+ assert_format!(r#"
fn foo() {
( 14 + 42 ) * 1337
}
@@ -366,24 +184,12 @@ fn test_block_arithmetic_expr() {
fn bar() {
{ 14 + 42 } * 1337
}
- "#};
-
- let expected = indoc! {r#"
- fn foo() {
- ( 14 + 42 ) * 1337
- }
-
- fn bar() {
- ( 14 + 42 ) * 1337
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn test_block_logical_expr() {
- let src = indoc! {r#"
+fn test_format_block_logical_expr() {
+ assert_format!(r#"
fn foo() {
!(a && b)
}
@@ -395,28 +201,12 @@ fn test_block_logical_expr() {
fn baz() {
a || (b && c) || d
}
- "#};
-
- let expected = indoc! {r#"
- fn foo() {
- !(a && b)
- }
-
- fn bar() {
- ( a || b ) && ( c || d )
- }
-
- fn baz() {
- a || b && c || d
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn test_nested_function_calls() {
- let src = indoc! {r#"
+fn test_format_nested_function_calls() {
+ assert_format!(r#"
fn foo(output) {
[
output.address.stake_credential == Some(
@@ -433,33 +223,12 @@ fn test_nested_function_calls() {
]
|> list.and
}
- "#};
-
- let expected = indoc! {r#"
- fn foo(output) {
- [
- output.address.stake_credential == Some(
- Inline(
- VerificationKeyCredential(
- #"66666666666666666666666666666666666666666666666666666666",
- ),
- ),
- ),
- when output.datum is {
- InlineDatum(_) -> True
- _ -> error @"expected inline datum"
- },
- ]
- |> list.and
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn format_trace_todo_error() {
- let src = indoc! {r#"
+fn test_format_trace_todo_error() {
+ assert_format!(r#"
fn foo_1() {
todo
}
@@ -483,40 +252,12 @@ fn format_trace_todo_error() {
True
}
}
- "#};
-
- let out = indoc! {r#"
- fn foo_1() {
- todo
- }
-
- fn foo_2() {
- todo @"my custom message"
- }
-
- fn foo_3() {
- when x is {
- Foo -> True
- _ -> error
- }
- }
-
- fn foo_4() {
- if 14 == 42 {
- error @"I don't think so"
- } else {
- trace @"been there"
- True
- }
- }
- "#};
-
- assert_fmt(src, out);
+ "#);
}
#[test]
-fn test_trace_if_false() {
- let src = indoc! {r#"
+fn test_format_trace_if_false() {
+ assert_format!(r#"
fn foo() {
my_expression?
}
@@ -524,14 +265,12 @@ fn test_trace_if_false() {
fn bar() {
(True && False)? || foo()?
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_newline_comments() {
- let src = indoc! {r#"
+fn test_format_newline_comments() {
+ assert_format!(r#"
// My comment
//
// has a newline.
@@ -545,14 +284,12 @@ fn test_newline_comments() {
fn bar() {
True
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_newline_doc_comments() {
- let src = indoc! {r#"
+fn test_format_newline_doc_comments() {
+ assert_format!(r#"
/// My doc comment
///
/// has a newline.
@@ -566,29 +303,12 @@ fn test_newline_doc_comments() {
fn bar() {
True
}
- "#};
-
- let out = indoc! {r#"
- /// My doc comment
- ///
- /// has a newline.
- fn foo() {
- True
- }
-
- /// My doc comments
- /// cannot be separated
- fn bar() {
- True
- }
- "#};
-
- assert_fmt(src, out);
+ "#);
}
#[test]
-fn test_newline_module_comments() {
- let src = indoc! {r#"
+fn test_format_newline_module_comments() {
+ assert_format!(r#"
//// My module comment
////
//// has a newline.
@@ -600,26 +320,12 @@ fn test_newline_module_comments() {
//// My module comments
//// cannot be separated
- "#};
-
- let out = indoc! {r#"
- //// My module comment
- ////
- //// has a newline.
- //// My module comments
- //// cannot be separated
-
- fn foo() {
- True
- }
- "#};
-
- assert_fmt(src, out);
+ "#);
}
#[test]
-fn test_bytearray_literals() {
- let src = indoc! {r#"
+fn test_format_bytearray_literals() {
+ assert_format!(r#"
const foo_const_array = #[102, 111, 111]
const foo_const_hex = #"666f6f"
@@ -633,40 +339,34 @@ fn test_bytearray_literals() {
let foo_const_utf8 = "foo"
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_string_literal() {
- let src = indoc! {r#"
+fn test_format_string_literal() {
+ assert_format!(r#"
const foo_const: String = @"foo"
fn foo() {
let foo_var: String = @"foo"
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_unicode() {
- let src = indoc! {r#"
+fn test_format_unicode() {
+ assert_format!(r#"
/// ∞ ★ ♩ ♫ ✓
fn foo() {
trace @"∀💩"
Void
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_preserve_pipe() {
- let src = indoc! { r#"
+fn test_format_preserve_pipe() {
+ assert_format!(r#"
fn foo() {
a |> b |> c |> d
}
@@ -683,37 +383,12 @@ fn test_preserve_pipe() {
// Commented
however |> it_automatically_breaks |> into_multiple_lines |> anytime_when |> it_is_too_long // What?
}
- "#};
-
- let expected = indoc! { r#"
- fn foo() {
- a |> b |> c |> d
- }
-
- fn foo() {
- a // Foo
- |> b // Some comments
- |> c
- |> d
- }
-
- fn baz() {
- // Commented
- however
- |> it_automatically_breaks
- |> into_multiple_lines
- |> anytime_when
- |> it_is_too_long
- // What?
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn weird_comments() {
- let src = indoc! { r#"
+fn test_format_weird_comments() {
+ assert_format!(r#"
// A
/// B
@@ -731,82 +406,35 @@ fn weird_comments() {
fn bar() {
todo
}
- "#};
-
- let expected = indoc! { r#"
- // A
-
- /// B
- /// C
- fn foo() {
- todo
- }
-
- // E
-
- // G
- /// F
- fn bar() {
- todo
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn format_trace_callback() {
- let src = indoc! { r#"
+fn test_format_trace_callback() {
+ assert_format!(r#"
fn foo() {
list.any([], fn (e) { trace @"foo"
e
})
}
- "#};
-
- let expected = indoc! { r#"
- fn foo() {
- list.any(
- [],
- fn(e) {
- trace @"foo"
- e
- },
- )
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn format_pipe_fn() {
- let src = indoc! { r#"
+fn test_format_pipe_fn() {
+ assert_format!(r#"
fn foo() {
outputs
|> list.any(
fn(output) { value.quantity_of(output.value, policy_id, asset_name) == 1 },
)
}
- "#};
-
- let expected = indoc! { r#"
- fn foo() {
- outputs
- |> list.any(
- fn(output) {
- value.quantity_of(output.value, policy_id, asset_name) == 1
- },
- )
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn match_record() {
- let src = indoc! { r#"
+fn test_format_match_record() {
+ assert_format!(r#"
fn foo() {
when bar is {
Bar { a, b, c } -> Void
@@ -816,58 +444,44 @@ fn match_record() {
Bar(..) -> Void
}
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn test_fail() {
- let src = indoc! { r#"
+fn test_format_fail() {
+ assert_format!(r#"
!test foo() {
expect Some(a) = bar
a
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn pipes_and_expressions() {
- let src = indoc! {r#"
+fn test_format_pipes_and_expressions() {
+ assert_format!(r#"
test fmt() {
(x == y) && ((z |> length()) == x)
}
- "#};
-
- let expected = indoc! {r#"
- test fmt() {
- x == y && ( z |> length() ) == x
- }
- "#};
-
- assert_fmt(src, expected);
+ "#);
}
#[test]
-fn hex_and_numeric_underscore() {
- let src = indoc! {r#"
+fn test_format_hex_and_numeric_underscore() {
+ assert_format!(r#"
fn foo() {
let a = 1_000_000 + 1_423 + 10393841
let b = 0xa4 - 0xcd
let c = #[0xfd, 0x12, 0x00, 0x1b, 0x0a, 0x90]
let d = -100_000
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
-fn first_class_binop() {
- let src = indoc! { r#"
+fn test_format_first_class_binop() {
+ assert_format!(r#"
fn foo() {
compare_with(a, >, b)
compare_with(a, >=, b)
@@ -883,9 +497,7 @@ fn first_class_binop() {
compute_with(a, *, b)
compute_with(a, %, b)
}
- "#};
-
- assert_fmt(src, src);
+ "#);
}
#[test]
diff --git a/crates/aiken-lang/src/tests/snapshots/format_block_arithmetic_expr.snap b/crates/aiken-lang/src/tests/snapshots/format_block_arithmetic_expr.snap
new file mode 100644
index 00000000..dfe16a2a
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_block_arithmetic_expr.snap
@@ -0,0 +1,12 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n ( 14 + 42 ) * 1337\n}\n\nfn bar() {\n { 14 + 42 } * 1337\n}\n"
+---
+fn foo() {
+ ( 14 + 42 ) * 1337
+}
+
+fn bar() {
+ ( 14 + 42 ) * 1337
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_block_logical_expr.snap b/crates/aiken-lang/src/tests/snapshots/format_block_logical_expr.snap
new file mode 100644
index 00000000..c73b2863
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_block_logical_expr.snap
@@ -0,0 +1,16 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n !(a && b)\n}\n\nfn bar() {\n (a || b) && (c || d)\n}\n\nfn baz() {\n a || (b && c) || d\n}\n"
+---
+fn foo() {
+ !(a && b)
+}
+
+fn bar() {
+ ( a || b ) && ( c || d )
+}
+
+fn baz() {
+ a || b && c || d
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_bytearray_literals.snap b/crates/aiken-lang/src/tests/snapshots/format_bytearray_literals.snap
new file mode 100644
index 00000000..87a1e8eb
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_bytearray_literals.snap
@@ -0,0 +1,18 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nconst foo_const_array = #[102, 111, 111]\n\nconst foo_const_hex = #\"666f6f\"\n\nconst foo_const_utf8 = \"foo\"\n\nfn foo() {\n let foo_const_array = #[102, 111, 111]\n\n let foo_const_hex = #\"666f6f\"\n\n let foo_const_utf8 = \"foo\"\n}\n"
+---
+const foo_const_array = #[102, 111, 111]
+
+const foo_const_hex = #"666f6f"
+
+const foo_const_utf8 = "foo"
+
+fn foo() {
+ let foo_const_array = #[102, 111, 111]
+
+ let foo_const_hex = #"666f6f"
+
+ let foo_const_utf8 = "foo"
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_comment_at_end_of_file.snap b/crates/aiken-lang/src/tests/snapshots/format_comment_at_end_of_file.snap
new file mode 100644
index 00000000..252ef514
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_comment_at_end_of_file.snap
@@ -0,0 +1,8 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\ntype Foo =\n Int\n\n//"
+---
+type Foo =
+ Int
+//
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap b/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap
new file mode 100644
index 00000000..61b9d549
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_double_validator.snap
@@ -0,0 +1,15 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n validator ( param1 : ByteArray ) {\n fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\n True\n }\n /// This is bar\nfn bar(r: Redeemer, ctx : ScriptContext ) -> Bool { True }\n }\n"
+---
+validator(param1: ByteArray) {
+ fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
+ True
+ }
+
+ /// This is bar
+ fn bar(r: Redeemer, ctx: ScriptContext) -> Bool {
+ True
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_else_if.snap b/crates/aiken-lang/src/tests/snapshots/format_else_if.snap
new file mode 100644
index 00000000..c1d81bb1
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_else_if.snap
@@ -0,0 +1,14 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\npub fn foo(xs: List, n: Int) -> List {\n if n <= 0 {\n xs\n } else if n <= 10 {\n xs\n } else {\n xs\n }\n}\n"
+---
+pub fn foo(xs: List, n: Int) -> List {
+ if n <= 0 {
+ xs
+ } else if n <= 10 {
+ xs
+ } else {
+ xs
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_fail.snap b/crates/aiken-lang/src/tests/snapshots/format_fail.snap
new file mode 100644
index 00000000..d3fe7f08
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_fail.snap
@@ -0,0 +1,10 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n!test foo() {\n expect Some(a) = bar\n\n a\n}\n"
+---
+!test foo() {
+ expect Some(a) = bar
+
+ a
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_first_class_binop.snap b/crates/aiken-lang/src/tests/snapshots/format_first_class_binop.snap
new file mode 100644
index 00000000..5aec4a32
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_first_class_binop.snap
@@ -0,0 +1,20 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n compare_with(a, >, b)\n compare_with(a, >=, b)\n compare_with(a, <, b)\n compare_with(a, <=, b)\n compare_with(a, ==, b)\n compare_with(a, !=, b)\n combine_with(a, &&, b)\n combine_with(a, ||, b)\n compute_with(a, +, b)\n compute_with(a, -, b)\n compute_with(a, /, b)\n compute_with(a, *, b)\n compute_with(a, %, b)\n}\n"
+---
+fn foo() {
+ compare_with(a, >, b)
+ compare_with(a, >=, b)
+ compare_with(a, <, b)
+ compare_with(a, <=, b)
+ compare_with(a, ==, b)
+ compare_with(a, !=, b)
+ combine_with(a, &&, b)
+ combine_with(a, ||, b)
+ compute_with(a, +, b)
+ compute_with(a, -, b)
+ compute_with(a, /, b)
+ compute_with(a, *, b)
+ compute_with(a, %, b)
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_hex_and_numeric_underscore.snap b/crates/aiken-lang/src/tests/snapshots/format_hex_and_numeric_underscore.snap
new file mode 100644
index 00000000..ce430459
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_hex_and_numeric_underscore.snap
@@ -0,0 +1,11 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n let a = 1_000_000 + 1_423 + 10393841\n let b = 0xa4 - 0xcd\n let c = #[0xfd, 0x12, 0x00, 0x1b, 0x0a, 0x90]\n let d = -100_000\n}\n"
+---
+fn foo() {
+ let a = 1_000_000 + 1_423 + 10393841
+ let b = 0xa4 - 0xcd
+ let c = #[0xfd, 0x12, 0x00, 0x1b, 0x0a, 0x90]
+ let d = -100_000
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_if.snap b/crates/aiken-lang/src/tests/snapshots/format_if.snap
new file mode 100644
index 00000000..69f3bdf6
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_if.snap
@@ -0,0 +1,25 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\npub fn foo(a) {\n if a { 14 } else { 42 }\n }\n\npub fn bar(xs) {\n list.map(xs, fn (x) { if x > 0 { \"foo\" } else { \"bar\" } })\n}\n"
+---
+pub fn foo(a) {
+ if a {
+ 14
+ } else {
+ 42
+ }
+}
+
+pub fn bar(xs) {
+ list.map(
+ xs,
+ fn(x) {
+ if x > 0 {
+ "foo"
+ } else {
+ "bar"
+ }
+ },
+ )
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_imports.snap b/crates/aiken-lang/src/tests/snapshots/format_imports.snap
new file mode 100644
index 00000000..b36b0c32
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_imports.snap
@@ -0,0 +1,12 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nuse aiken/list\n// foo\nuse aiken/bytearray\nuse aiken/transaction/certificate\n// bar\nuse aiken/transaction\nuse aiken/transaction/value\n"
+---
+// foo
+use aiken/bytearray
+use aiken/list
+// bar
+use aiken/transaction
+use aiken/transaction/certificate
+use aiken/transaction/value
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_match_record.snap b/crates/aiken-lang/src/tests/snapshots/format_match_record.snap
new file mode 100644
index 00000000..abf717db
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_match_record.snap
@@ -0,0 +1,14 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n when bar is {\n Bar { a, b, c } -> Void\n Bar { a, .. } -> Void\n Bar { .. } -> Void\n Bar(a, b, c) -> Void\n Bar(..) -> Void\n }\n}\n"
+---
+fn foo() {
+ when bar is {
+ Bar { a, b, c } -> Void
+ Bar { a, .. } -> Void
+ Bar { .. } -> Void
+ Bar(a, b, c) -> Void
+ Bar(..) -> Void
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_negate.snap b/crates/aiken-lang/src/tests/snapshots/format_negate.snap
new file mode 100644
index 00000000..343cfa8e
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_negate.snap
@@ -0,0 +1,8 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n - 42\n}\n"
+---
+fn foo() {
+ -42
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_nested_function_calls.snap b/crates/aiken-lang/src/tests/snapshots/format_nested_function_calls.snap
new file mode 100644
index 00000000..b072e1d0
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_nested_function_calls.snap
@@ -0,0 +1,21 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo(output) {\n [\n output.address.stake_credential == Some(\n Inline(\n VerificationKeyCredential(\n #\"66666666666666666666666666666666666666666666666666666666\",\n ))\n )\n ,\n when output.datum is {\n InlineDatum(_) -> True\n _ -> error \"expected inline datum\"\n },\n ]\n |> list.and\n}\n"
+---
+fn foo(output) {
+ [
+ output.address.stake_credential == Some(
+ Inline(
+ VerificationKeyCredential(
+ #"66666666666666666666666666666666666666666666666666666666",
+ ),
+ ),
+ ),
+ when output.datum is {
+ InlineDatum(_) -> True
+ _ -> error @"expected inline datum"
+ },
+ ]
+ |> list.and
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_nested_if.snap b/crates/aiken-lang/src/tests/snapshots/format_nested_if.snap
new file mode 100644
index 00000000..311aac9b
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_nested_if.snap
@@ -0,0 +1,24 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\npub fn foo(n) {\n if n > 0 {\n if n > 1 { if n > 2 { \"foo\" } else { \"foo\" } } else { \"bar\" }\n } else {\n if n < -1 { \"baz\" } else { \"biz\" }\n }\n}\n"
+---
+pub fn foo(n) {
+ if n > 0 {
+ if n > 1 {
+ if n > 2 {
+ "foo"
+ } else {
+ "foo"
+ }
+ } else {
+ "bar"
+ }
+ } else {
+ if n < -1 {
+ "baz"
+ } else {
+ "biz"
+ }
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_nested_when.snap b/crates/aiken-lang/src/tests/snapshots/format_nested_when.snap
new file mode 100644
index 00000000..29e8e709
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_nested_when.snap
@@ -0,0 +1,19 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n when a is {\n None -> \"foo\"\n Some(b) -> when b is {\n None -> \"foo\"\n Some(c) -> when c is {\n None -> \"foo\"\n Some(_) -> \"foo\"\n }\n }\n }\n}\n"
+---
+fn foo() {
+ when a is {
+ None -> "foo"
+ Some(b) ->
+ when b is {
+ None -> "foo"
+ Some(c) ->
+ when c is {
+ None -> "foo"
+ Some(_) -> "foo"
+ }
+ }
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_nested_when_if.snap b/crates/aiken-lang/src/tests/snapshots/format_nested_when_if.snap
new file mode 100644
index 00000000..60acdd97
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_nested_when_if.snap
@@ -0,0 +1,16 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\npub fn drop(xs: List, n: Int) -> List {\n if n <= 0 {\n xs\n } else {\n when xs is {\n [] ->\n []\n [_x, ..rest] ->\n drop(rest, n - 1)\n }\n }\n}\n"
+---
+pub fn drop(xs: List, n: Int) -> List {
+ if n <= 0 {
+ xs
+ } else {
+ when xs is {
+ [] ->
+ []
+ [_x, ..rest] -> drop(rest, n - 1)
+ }
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_newline_comments.snap b/crates/aiken-lang/src/tests/snapshots/format_newline_comments.snap
new file mode 100644
index 00000000..166d8785
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_newline_comments.snap
@@ -0,0 +1,18 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n// My comment\n//\n// has a newline.\nfn foo() {\n True\n}\n\n// My comments\n\n// can live apart\nfn bar() {\n True\n}\n"
+---
+// My comment
+//
+// has a newline.
+fn foo() {
+ True
+}
+
+// My comments
+
+// can live apart
+fn bar() {
+ True
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_newline_doc_comments.snap b/crates/aiken-lang/src/tests/snapshots/format_newline_doc_comments.snap
new file mode 100644
index 00000000..726fc61e
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_newline_doc_comments.snap
@@ -0,0 +1,17 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n/// My doc comment\n///\n/// has a newline.\nfn foo() {\n True\n}\n\n/// My doc comments\n\n/// cannot be separated\nfn bar() {\n True\n}\n"
+---
+/// My doc comment
+///
+/// has a newline.
+fn foo() {
+ True
+}
+
+/// My doc comments
+/// cannot be separated
+fn bar() {
+ True
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_newline_module_comments.snap b/crates/aiken-lang/src/tests/snapshots/format_newline_module_comments.snap
new file mode 100644
index 00000000..42a04eb4
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_newline_module_comments.snap
@@ -0,0 +1,14 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n//// My module comment\n////\n//// has a newline.\n\nfn foo() {\n True\n}\n\n//// My module comments\n\n//// cannot be separated\n"
+---
+//// My module comment
+////
+//// has a newline.
+//// My module comments
+//// cannot be separated
+
+fn foo() {
+ True
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_pipe_fn.snap b/crates/aiken-lang/src/tests/snapshots/format_pipe_fn.snap
new file mode 100644
index 00000000..6912566d
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_pipe_fn.snap
@@ -0,0 +1,13 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n outputs\n |> list.any(\n fn(output) { value.quantity_of(output.value, policy_id, asset_name) == 1 },\n )\n}\n"
+---
+fn foo() {
+ outputs
+ |> list.any(
+ fn(output) {
+ value.quantity_of(output.value, policy_id, asset_name) == 1
+ },
+ )
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_pipes_and_expressions.snap b/crates/aiken-lang/src/tests/snapshots/format_pipes_and_expressions.snap
new file mode 100644
index 00000000..e0acd8ed
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_pipes_and_expressions.snap
@@ -0,0 +1,8 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\ntest fmt() {\n (x == y) && ((z |> length()) == x)\n}\n"
+---
+test fmt() {
+ x == y && ( z |> length() ) == x
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_preserve_pipe.snap b/crates/aiken-lang/src/tests/snapshots/format_preserve_pipe.snap
new file mode 100644
index 00000000..b128f5e2
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_preserve_pipe.snap
@@ -0,0 +1,25 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n a |> b |> c |> d\n}\n\nfn foo() {\n a\n // Foo\n |> b// Some comments\n |> c\n |> d\n}\n\nfn baz() {\n // Commented\n however |> it_automatically_breaks |> into_multiple_lines |> anytime_when |> it_is_too_long // What?\n}\n"
+---
+fn foo() {
+ a |> b |> c |> d
+}
+
+fn foo() {
+ a // Foo
+ |> b // Some comments
+ |> c
+ |> d
+}
+
+fn baz() {
+ // Commented
+ however
+ |> it_automatically_breaks
+ |> into_multiple_lines
+ |> anytime_when
+ |> it_is_too_long
+ // What?
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_simple_module.snap b/crates/aiken-lang/src/tests/snapshots/format_simple_module.snap
new file mode 100644
index 00000000..e616d1d8
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_simple_module.snap
@@ -0,0 +1,8 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn smth() { let a = foo.Foo { bar: 1 } }\n"
+---
+fn smth() {
+ let a = foo.Foo { bar: 1 }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_string_literal.snap b/crates/aiken-lang/src/tests/snapshots/format_string_literal.snap
new file mode 100644
index 00000000..f14a06ca
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_string_literal.snap
@@ -0,0 +1,10 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nconst foo_const: String = @\"foo\"\n\nfn foo() {\n let foo_var: String = @\"foo\"\n}\n"
+---
+const foo_const: String = @"foo"
+
+fn foo() {
+ let foo_var: String = @"foo"
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_trace_callback.snap b/crates/aiken-lang/src/tests/snapshots/format_trace_callback.snap
new file mode 100644
index 00000000..1028eed7
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_trace_callback.snap
@@ -0,0 +1,14 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n list.any([], fn (e) { trace @\"foo\"\n e\n })\n}\n"
+---
+fn foo() {
+ list.any(
+ [],
+ fn(e) {
+ trace @"foo"
+ e
+ },
+ )
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_trace_if_false.snap b/crates/aiken-lang/src/tests/snapshots/format_trace_if_false.snap
new file mode 100644
index 00000000..6190469a
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_trace_if_false.snap
@@ -0,0 +1,12 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo() {\n my_expression?\n}\n\nfn bar() {\n (True && False)? || foo()?\n}\n"
+---
+fn foo() {
+ my_expression?
+}
+
+fn bar() {
+ (True && False)? || foo()?
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_trace_todo_error.snap b/crates/aiken-lang/src/tests/snapshots/format_trace_todo_error.snap
new file mode 100644
index 00000000..a41a4be8
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_trace_todo_error.snap
@@ -0,0 +1,28 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nfn foo_1() {\n todo\n}\n\nfn foo_2() {\n todo \"my custom message\"\n}\n\nfn foo_3() {\n when x is {\n Foo -> True\n _ -> error\n }\n}\n\nfn foo_4() {\n if 14 == 42 {\n error \"I don't think so\"\n } else {\n trace \"been there\"\n True\n }\n}\n"
+---
+fn foo_1() {
+ todo
+}
+
+fn foo_2() {
+ todo @"my custom message"
+}
+
+fn foo_3() {
+ when x is {
+ Foo -> True
+ _ -> error
+ }
+}
+
+fn foo_4() {
+ if 14 == 42 {
+ error @"I don't think so"
+ } else {
+ trace @"been there"
+ True
+ }
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_unicode.snap b/crates/aiken-lang/src/tests/snapshots/format_unicode.snap
new file mode 100644
index 00000000..e89e63d5
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_unicode.snap
@@ -0,0 +1,10 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n/// ∞ ★ ♩ ♫ ✓\nfn foo() {\n trace @\"∀💩\"\n Void\n}\n"
+---
+/// ∞ ★ ♩ ♫ ✓
+fn foo() {
+ trace @"∀💩"
+ Void
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_validator.snap b/crates/aiken-lang/src/tests/snapshots/format_validator.snap
new file mode 100644
index 00000000..1dd22f0b
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_validator.snap
@@ -0,0 +1,22 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\nvalidator ( ) {\n// What is the purpose of life\n\nfn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {\nTrue\n}\n}\n\n// What?\nvalidator {\n /// Some documentation for foo\n fn foo() {\n Void\n }\n\n // I am lost\n}\n"
+---
+validator {
+ // What is the purpose of life
+
+ fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
+ True
+ }
+}
+
+// What?
+validator {
+ /// Some documentation for foo
+ fn foo() {
+ Void
+ }
+
+ // I am lost
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_weird_comments.snap b/crates/aiken-lang/src/tests/snapshots/format_weird_comments.snap
new file mode 100644
index 00000000..93766938
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_weird_comments.snap
@@ -0,0 +1,20 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\n// A\n\n/// B\n\n/// C\nfn foo() {\n todo\n}\n\n// E\n\n/// F\n\n// G\nfn bar() {\n todo\n}\n"
+---
+// A
+
+/// B
+/// C
+fn foo() {
+ todo
+}
+
+// E
+
+// G
+/// F
+fn bar() {
+ todo
+}
+
diff --git a/crates/aiken-lang/src/tests/snapshots/format_when.snap b/crates/aiken-lang/src/tests/snapshots/format_when.snap
new file mode 100644
index 00000000..de87e6f6
--- /dev/null
+++ b/crates/aiken-lang/src/tests/snapshots/format_when.snap
@@ -0,0 +1,16 @@
+---
+source: crates/aiken-lang/src/tests/format.rs
+description: "Code:\n\npub fn foo( a) {\n when a is{\n True -> {\n\n bar()\n\n 14\n\n }\n False ->\n\n 42\n\n }\n }\n"
+---
+pub fn foo(a) {
+ when a is {
+ True -> {
+ bar()
+
+ 14
+ }
+
+ False -> 42
+ }
+}
+