mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Assert formatting for parse tests
This commit is contained in:
parent
1efd7260de
commit
d4bf946327
105 changed files with 495 additions and 12 deletions
|
@ -5,6 +5,8 @@ extern crate roc_fmt;
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_fmt {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use bumpalo::Bump;
|
||||
use roc_fmt::annotation::{Formattable, Newlines, Parens};
|
||||
use roc_fmt::def::fmt_defs;
|
||||
|
@ -21,10 +23,9 @@ mod test_fmt {
|
|||
/// parses without error, formats without error, and
|
||||
/// (optionally, based on the value of `check_stability`) re-parses to
|
||||
/// the same AST as the original.
|
||||
fn expr_formats(input: &str, expected: Option<&str>, check_stability: bool) {
|
||||
fn expr_formats(input: &str, check_formatting: impl Fn(&str), check_stability: bool) {
|
||||
let arena = Bump::new();
|
||||
let input = input.trim();
|
||||
let expected = expected.map(|e| e.trim());
|
||||
|
||||
match roc_parse::test_helpers::parse_expr_with(&arena, input) {
|
||||
Ok(actual) => {
|
||||
|
@ -36,9 +37,7 @@ mod test_fmt {
|
|||
|
||||
let output = buf.as_str();
|
||||
|
||||
if let Some(expected) = expected {
|
||||
assert_multiline_str_eq!(expected, output);
|
||||
}
|
||||
check_formatting(output);
|
||||
|
||||
let reparsed_ast = roc_parse::test_helpers::parse_expr_with(&arena, output).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
|
@ -84,12 +83,19 @@ mod test_fmt {
|
|||
};
|
||||
}
|
||||
|
||||
fn check_formatting(expected: &'_ str) -> impl Fn(&str) + '_ {
|
||||
let expected = expected.trim();
|
||||
move |output| {
|
||||
assert_multiline_str_eq!(expected, output);
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_formats_to(input: &str, expected: &str) {
|
||||
expr_formats(input, Some(expected), true);
|
||||
expr_formats(input, check_formatting(expected), true);
|
||||
}
|
||||
|
||||
fn expr_formats_same(input: &str) {
|
||||
expr_formats(input, Some(input), true);
|
||||
expr_formats(input, check_formatting(input), true);
|
||||
}
|
||||
|
||||
fn fmt_module_and_defs<'a>(
|
||||
|
@ -5850,12 +5856,63 @@ mod test_fmt {
|
|||
.collect::<std::vec::Vec<_>>()
|
||||
}
|
||||
|
||||
fn check_saved_formatting(original: &'_ str, result_path: PathBuf) -> impl Fn(&str) + '_ {
|
||||
move |actual_result: &str| {
|
||||
if std::env::var("ROC_SNAPSHOT_TEST_OVERWRITE").is_ok() {
|
||||
if original == actual_result {
|
||||
std::fs::remove_file(&result_path)
|
||||
.or_else(|e| {
|
||||
if e.kind() == std::io::ErrorKind::NotFound {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
} else {
|
||||
std::fs::write(&result_path, actual_result).unwrap();
|
||||
}
|
||||
} else if original == actual_result {
|
||||
// We represent this expectation on the filesystem as the _absence_ of the .formatted.expr.roc file.
|
||||
// This makes the directory a bit cleaner.
|
||||
|
||||
assert!(!result_path.exists(),
|
||||
"Expected no file at {}\n\
|
||||
This how we represent the expectation that the formatting of the input file should not change.\n\
|
||||
consider running the tests with:\n\
|
||||
`env ROC_SNAPSHOT_TEST_OVERWRITE=1 cargo test ...` (which will delete the file for you),\n\
|
||||
and commiting the delete.",
|
||||
result_path.display());
|
||||
} else {
|
||||
let expected_result =
|
||||
std::fs::read_to_string(&result_path).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Error opening test output file {}:\n\
|
||||
{:?}
|
||||
Supposing the file is missing, consider running the tests with:\n\
|
||||
`env ROC_SNAPSHOT_TEST_OVERWRITE=1 cargo test ...`\n\
|
||||
and committing the file that creates.",
|
||||
result_path.display(),
|
||||
e
|
||||
);
|
||||
});
|
||||
|
||||
assert_multiline_str_eq!(expected_result.as_str(), actual_result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let base = std::path::PathBuf::from("../parse/tests/snapshots/pass");
|
||||
for file in list(&base) {
|
||||
if file.ends_with(".expr.roc") {
|
||||
if let Some(prefix) = file.strip_suffix(".expr.roc") {
|
||||
println!("formatting {}", file);
|
||||
let contents = std::fs::read_to_string(base.join(file)).unwrap();
|
||||
expr_formats(&contents, None, false);
|
||||
let contents = std::fs::read_to_string(base.join(&file)).unwrap();
|
||||
let formatted_path = base.join(format!("{}.expr.formatted.roc", prefix));
|
||||
expr_formats(
|
||||
&contents,
|
||||
check_saved_formatting(&contents, formatted_path),
|
||||
false,
|
||||
);
|
||||
} else if file.ends_with(".module.roc") {
|
||||
// TODO: re-format module defs and ensure they're correct.
|
||||
// Note that these tests don't have an actual module header,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Hash has
|
||||
hash : a -> U64
|
||||
|
||||
1
|
|
@ -0,0 +1,5 @@
|
|||
Hash has
|
||||
hash : a -> U64
|
||||
hash2 : a -> U64
|
||||
|
||||
1
|
|
@ -0,0 +1,3 @@
|
|||
Hash has hash : a -> U64 | a has Hash
|
||||
|
||||
1
|
|
@ -0,0 +1,5 @@
|
|||
Ab1 has ab1 : a -> {} | a has Ab1
|
||||
|
||||
Ab2 has ab2 : a -> {} | a has Ab2
|
||||
|
||||
1
|
|
@ -0,0 +1 @@
|
|||
1 + 2
|
|
@ -0,0 +1,4 @@
|
|||
{ x, y } : Foo
|
||||
{ x, y } = { x: "foo", y: 3.14 }
|
||||
|
||||
x
|
|
@ -0,0 +1,4 @@
|
|||
UserId x : [UserId I64]
|
||||
(UserId x) = UserId 42
|
||||
|
||||
x
|
|
@ -0,0 +1,4 @@
|
|||
(x, y) : Foo
|
||||
(x, y) = ("foo", 3.14)
|
||||
|
||||
x
|
|
@ -0,0 +1 @@
|
|||
whee 12 34
|
|
@ -0,0 +1 @@
|
|||
-whee 12 foo
|
|
@ -0,0 +1 @@
|
|||
!whee 12 foo
|
|
@ -0,0 +1,9 @@
|
|||
## first line of docs
|
||||
## second line
|
||||
## third line
|
||||
## fourth line
|
||||
##
|
||||
## sixth line after doc new line
|
||||
x = 5
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
12
|
||||
* # test!
|
||||
92
|
|
@ -0,0 +1,2 @@
|
|||
3 # test!
|
||||
+ 4
|
|
@ -0,0 +1,2 @@
|
|||
[ # comment
|
||||
]
|
|
@ -0,0 +1,2 @@
|
|||
3 # 2 × 2
|
||||
+ 4
|
|
@ -0,0 +1,3 @@
|
|||
(Email str) = Email "blah@example.com"
|
||||
|
||||
str
|
|
@ -0,0 +1 @@
|
|||
""
|
|
@ -0,0 +1 @@
|
|||
x == y
|
|
@ -0,0 +1,4 @@
|
|||
expect
|
||||
1 == 1
|
||||
|
||||
4
|
|
@ -0,0 +1,3 @@
|
|||
iffy = 5
|
||||
|
||||
42
|
|
@ -0,0 +1,2 @@
|
|||
\x ->
|
||||
1
|
|
@ -0,0 +1,10 @@
|
|||
my_list = [
|
||||
0,
|
||||
[
|
||||
a,
|
||||
b,
|
||||
],
|
||||
1,
|
||||
]
|
||||
|
||||
42
|
|
@ -0,0 +1,6 @@
|
|||
my_list = [
|
||||
0,
|
||||
1,
|
||||
]
|
||||
|
||||
42
|
|
@ -0,0 +1,6 @@
|
|||
my_list = [
|
||||
0,
|
||||
1,
|
||||
]
|
||||
|
||||
42
|
|
@ -0,0 +1,9 @@
|
|||
when [] is
|
||||
[] -> {}
|
||||
[..] -> {}
|
||||
[_, .., _, ..] -> {}
|
||||
[a, b, c, d] -> {}
|
||||
[a, b, ..] -> {}
|
||||
[.., c, d] -> {}
|
||||
[[A], [..], [a]] -> {}
|
||||
[[[], []], [[], x]] -> {}
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
bar.and -> 1
|
||||
_ -> 4
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
Foo.and -> 1
|
||||
_ -> 4
|
|
@ -0,0 +1 @@
|
|||
-12 - 5
|
|
@ -0,0 +1,7 @@
|
|||
# ## not docs!
|
||||
## docs, but with a problem
|
||||
## (namely that this is a mix of docs and regular comments)
|
||||
# not docs
|
||||
x = 5
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
x, y <- List.map2 [] []
|
||||
|
||||
x + y
|
|
@ -0,0 +1 @@
|
|||
"foo"
|
|
@ -0,0 +1,13 @@
|
|||
a = "Hello,\n\nWorld!"
|
||||
b =
|
||||
"""
|
||||
Hello,\n\nWorld!
|
||||
"""
|
||||
c =
|
||||
"""
|
||||
Hello,
|
||||
|
||||
World!
|
||||
"""
|
||||
|
||||
42
|
|
@ -0,0 +1,5 @@
|
|||
f :
|
||||
# comment
|
||||
{}
|
||||
|
||||
42
|
|
@ -0,0 +1 @@
|
|||
31 * 42 + 534
|
|
@ -0,0 +1,6 @@
|
|||
if t1 then
|
||||
1
|
||||
else if t2 then
|
||||
2
|
||||
else
|
||||
3
|
|
@ -0,0 +1,4 @@
|
|||
x =
|
||||
5
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
3
|
||||
*
|
||||
4
|
|
@ -0,0 +1,3 @@
|
|||
3
|
||||
-
|
||||
4
|
|
@ -0,0 +1,5 @@
|
|||
x =
|
||||
1
|
||||
< 2
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
1,
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
# ######
|
||||
# ## not docs!
|
||||
# #still not docs
|
||||
# #####
|
||||
x = 5
|
||||
|
||||
42
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
u8: 123u8,
|
||||
u16: 123u16,
|
||||
u32: 123u32,
|
||||
u64: 123u64,
|
||||
u128: 123u128,
|
||||
i8: 123i8,
|
||||
i16: 123i16,
|
||||
i32: 123i32,
|
||||
i64: 123i64,
|
||||
i128: 123i128,
|
||||
nat: 123nat,
|
||||
dec: 123dec,
|
||||
u8Neg: -123u8,
|
||||
u16Neg: -123u16,
|
||||
u32Neg: -123u32,
|
||||
u64Neg: -123u64,
|
||||
u128Neg: -123u128,
|
||||
i8Neg: -123i8,
|
||||
i16Neg: -123i16,
|
||||
i32Neg: -123i32,
|
||||
i64Neg: -123i64,
|
||||
i128Neg: -123i128,
|
||||
natNeg: -123nat,
|
||||
decNeg: -123dec,
|
||||
u8Bin: 0b101u8,
|
||||
u16Bin: 0b101u16,
|
||||
u32Bin: 0b101u32,
|
||||
u64Bin: 0b101u64,
|
||||
u128Bin: 0b101u128,
|
||||
i8Bin: 0b101i8,
|
||||
i16Bin: 0b101i16,
|
||||
i32Bin: 0b101i32,
|
||||
i64Bin: 0b101i64,
|
||||
i128Bin: 0b101i128,
|
||||
natBin: 0b101nat,
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
# leading comment
|
||||
x <- \y -> y
|
||||
|
||||
x
|
|
@ -0,0 +1 @@
|
|||
"x"
|
|
@ -0,0 +1,4 @@
|
|||
# leading comment
|
||||
x = 5
|
||||
|
||||
42
|
|
@ -0,0 +1 @@
|
|||
1 - 2
|
|
@ -0,0 +1 @@
|
|||
1 + 2
|
|
@ -0,0 +1,4 @@
|
|||
# leading comment
|
||||
x = 5
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
(@Thunk it) = id (@A {})
|
||||
|
||||
it {}
|
|
@ -0,0 +1,24 @@
|
|||
A := U8 has [Eq, Hash]
|
||||
|
||||
A := a | a has Other
|
||||
has [Eq, Hash]
|
||||
|
||||
A := a | a has Other
|
||||
has [Eq, Hash]
|
||||
|
||||
A := U8 has [Eq { eq }, Hash { hash }]
|
||||
|
||||
A := U8 has [Eq { eq, eq1 }]
|
||||
|
||||
A := U8 has [Eq { eq, eq1 }, Hash]
|
||||
|
||||
A := U8 has [Hash, Eq { eq, eq1 }]
|
||||
|
||||
A := U8 has []
|
||||
|
||||
A := a | a has Other
|
||||
has [Eq { eq }, Hash { hash }]
|
||||
|
||||
A := U8 has [Eq {}]
|
||||
|
||||
0
|
|
@ -0,0 +1 @@
|
|||
@Age
|
|
@ -0,0 +1 @@
|
|||
@Age m n
|
|
@ -0,0 +1,2 @@
|
|||
when n is
|
||||
@Age -> 1
|
|
@ -0,0 +1,2 @@
|
|||
when n is
|
||||
@Add n m -> n + m
|
|
@ -0,0 +1,4 @@
|
|||
3
|
||||
+
|
||||
|
||||
4
|
|
@ -0,0 +1,8 @@
|
|||
x = foo
|
||||
(
|
||||
baz {
|
||||
bar: blah,
|
||||
}
|
||||
)
|
||||
|
||||
x
|
|
@ -0,0 +1,7 @@
|
|||
a = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
|
||||
a
|
|
@ -0,0 +1,5 @@
|
|||
x = foo {
|
||||
bar: blah,
|
||||
}
|
||||
|
||||
x
|
|
@ -0,0 +1 @@
|
|||
whee
|
|
@ -0,0 +1,3 @@
|
|||
Blah a b : Foo.Bar.Baz x y
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
foo : Foo.Bar.Baz x y as Blah a b
|
||||
|
||||
42
|
|
@ -0,0 +1,2 @@
|
|||
when Delmin (Del rx) 0 is
|
||||
Delmin (Del ry) _ -> Node Black 0 Bool.false ry
|
|
@ -0,0 +1 @@
|
|||
1 * if Bool.true then 1 else 1
|
|
@ -0,0 +1,5 @@
|
|||
1
|
||||
+
|
||||
when Foo is
|
||||
Foo -> 2
|
||||
Bar -> 3
|
|
@ -0,0 +1,5 @@
|
|||
# leading comment
|
||||
{ x, y } = 5
|
||||
y = 6
|
||||
|
||||
42
|
|
@ -0,0 +1,8 @@
|
|||
f : {
|
||||
getLine : Effect Str,
|
||||
putLine : Str -> Effect Int,
|
||||
text : Str,
|
||||
value : Int *,
|
||||
}
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
x : { init : {} -> Model, update : Model, Str -> Model, view : Model -> Str }
|
||||
|
||||
42
|
|
@ -0,0 +1 @@
|
|||
{ x: if Bool.true then 1 else 2, y: 3 }
|
|
@ -0,0 +1 @@
|
|||
x - y
|
|
@ -0,0 +1 @@
|
|||
[1]
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1 @@
|
|||
1 - 2
|
|
@ -0,0 +1 @@
|
|||
10 * 11
|
|
@ -0,0 +1,5 @@
|
|||
# leading comment
|
||||
x <- \y -> y
|
||||
z <- {}
|
||||
|
||||
x
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
"" -> 1
|
||||
"mise" -> 2
|
|
@ -0,0 +1,5 @@
|
|||
# leading comment
|
||||
x = 5
|
||||
y = 6
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
doStuff : UserId -> Task Str _
|
||||
|
||||
42
|
|
@ -0,0 +1 @@
|
|||
whee 12 -foo
|
|
@ -0,0 +1 @@
|
|||
-(whee 12 foo)
|
|
@ -0,0 +1 @@
|
|||
!(whee 12 foo)
|
|
@ -0,0 +1,4 @@
|
|||
# leading comment
|
||||
_ <- \y -> y
|
||||
|
||||
4
|
|
@ -0,0 +1,7 @@
|
|||
(Pair x _) = Pair 0 1
|
||||
(Pair _ y) = Pair 0 1
|
||||
(Pair _ _) = Pair 0 1
|
||||
_ = Pair 0 1
|
||||
(Pair (Pair x _) (Pair _ y)) = Pair (Pair 0 1) (Pair 2 3)
|
||||
|
||||
0
|
|
@ -0,0 +1 @@
|
|||
x - 2
|
|
@ -0,0 +1,9 @@
|
|||
when x is
|
||||
_ ->
|
||||
1
|
||||
|
||||
_ ->
|
||||
2
|
||||
|
||||
Ok ->
|
||||
3
|
|
@ -0,0 +1,4 @@
|
|||
x = when n is
|
||||
0 -> 0
|
||||
|
||||
42
|
|
@ -0,0 +1,4 @@
|
|||
func = \x -> when n is
|
||||
0 -> 0
|
||||
|
||||
42
|
|
@ -0,0 +1,4 @@
|
|||
func = \x -> when n is
|
||||
0 -> 0
|
||||
|
||||
42
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
Ok ->
|
||||
3
|
|
@ -0,0 +1,2 @@
|
|||
when x is
|
||||
Ok -> 3
|
|
@ -0,0 +1,7 @@
|
|||
when x is
|
||||
"blah" | "blop" -> 1
|
||||
"foo"
|
||||
| "bar"
|
||||
| "baz" -> 2
|
||||
|
||||
"stuff" -> 4
|
|
@ -0,0 +1,6 @@
|
|||
when x is
|
||||
1 ->
|
||||
Num.neg
|
||||
2
|
||||
|
||||
_ -> 4
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
1 -> 2
|
||||
-3 -> 4
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
1 -> 2
|
||||
3 -> 4
|
|
@ -0,0 +1,3 @@
|
|||
when x is
|
||||
{ y } -> 2
|
||||
{ z, w } -> 4
|
|
@ -0,0 +1,3 @@
|
|||
when { foo: (1, 2) } is
|
||||
{ foo: (1, x) } -> x
|
||||
{ foo: (_, b) } -> 3 + b
|
|
@ -0,0 +1,3 @@
|
|||
when (1, 2) is
|
||||
(1, x) -> x
|
||||
(_, b) -> 3 + b
|
|
@ -0,0 +1,3 @@
|
|||
f : a -> (b -> c) | a has A
|
||||
|
||||
f
|
|
@ -0,0 +1,7 @@
|
|||
f : a -> b | a has Hash & Eq, b has Eq & Hash & Display
|
||||
|
||||
f :
|
||||
a
|
||||
-> b | a has Hash & Eq, b has Hash & Display & Eq
|
||||
|
||||
f
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue