diff --git a/compiler/parse/tests/snapshots/pass/empty_app_header.header.result-ast b/compiler/parse/tests/snapshots/pass/empty_app_header.header.result-ast new file mode 100644 index 0000000000..a8d7a076dc --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_app_header.header.result-ast @@ -0,0 +1,19 @@ +App { + header: AppHeader { + name: |L 0-0, C 4-14| PlainLine("test-app"), + packages: [], + imports: [], + provides: [], + to: |L 0-0, C 53-57| ExistingPackage("blah"), + before_header: [], + after_app_keyword: [], + before_packages: [], + after_packages: [], + before_imports: [], + after_imports: [], + before_provides: [], + after_provides: [], + before_to: [], + after_to: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/empty_app_header.header.roc b/compiler/parse/tests/snapshots/pass/empty_app_header.header.roc new file mode 100644 index 0000000000..e524c249e9 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_app_header.header.roc @@ -0,0 +1 @@ +app "test-app" packages {} imports [] provides [] to blah diff --git a/compiler/parse/tests/snapshots/pass/empty_interface_header.header.result-ast b/compiler/parse/tests/snapshots/pass/empty_interface_header.header.result-ast new file mode 100644 index 0000000000..f0ad966519 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_interface_header.header.result-ast @@ -0,0 +1,13 @@ +Interface { + header: InterfaceHeader { + name: |L 0-0, C 10-13| ModuleName("Foo"), + exposes: [], + imports: [], + before_header: [], + after_interface_keyword: [], + before_exposes: [], + after_exposes: [], + before_imports: [], + after_imports: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/empty_interface_header.header.roc b/compiler/parse/tests/snapshots/pass/empty_interface_header.header.roc new file mode 100644 index 0000000000..5959237bda --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_interface_header.header.roc @@ -0,0 +1 @@ +interface Foo exposes [] imports [] diff --git a/compiler/parse/tests/snapshots/pass/empty_platform_header.header.result-ast b/compiler/parse/tests/snapshots/pass/empty_platform_header.header.result-ast new file mode 100644 index 0000000000..7ce3a5f245 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_platform_header.header.result-ast @@ -0,0 +1,33 @@ +Platform { + header: PlatformHeader { + name: |L 0-0, C 9-23| PackageName { account: "rtfeldman", pkg: "blah" }, + requires: PlatformRequires { + rigids: [], + signature: |L 0-0, C 38-47| Entry { ident: |L 0-0, C 38-42| "main", spaces_before_colon: [], ann: |L 0-0, C 45-47| Record { fields: [], ext: None } }, + }, + exposes: [], + packages: [], + imports: [], + provides: [], + effects: Effects { + spaces_before_effects_keyword: [], + spaces_after_effects_keyword: [], + spaces_after_type_name: [], + effect_shortname: "fx", + effect_type_name: "Blah", + entries: [], + }, + before_header: [], + after_platform_keyword: [], + before_requires: [], + after_requires: [], + before_exposes: [], + after_exposes: [], + before_packages: [], + after_packages: [], + before_imports: [], + after_imports: [], + before_provides: [], + after_provides: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/empty_platform_header.header.roc b/compiler/parse/tests/snapshots/pass/empty_platform_header.header.roc new file mode 100644 index 0000000000..86550152a0 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/empty_platform_header.header.roc @@ -0,0 +1 @@ +platform rtfeldman/blah requires {} { main : {} } exposes [] packages {} imports [] provides [] effects fx.Blah {} \ No newline at end of file diff --git a/compiler/parse/tests/snapshots/pass/full_app_header.header.result-ast b/compiler/parse/tests/snapshots/pass/full_app_header.header.result-ast new file mode 100644 index 0000000000..d66ee260f5 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/full_app_header.header.result-ast @@ -0,0 +1,31 @@ +App { + header: AppHeader { + name: |L 0-0, C 4-15| PlainLine("quicksort"), + packages: [ + |L 1-1, C 15-33| Entry { shorthand: "base", spaces_after_shorthand: [], package_or_path: |L 1-1, C 21-33| Path(PlainLine("./platform")) }, + ], + imports: [ + |L 2-2, C 14-25| Package("foo", ModuleName("Bar.Baz"), []), + ], + provides: [ + |L 3-3, C 15-24| Exposed("quicksort"), + ], + to: |L 3-3, C 30-34| ExistingPackage("base"), + before_header: [], + after_app_keyword: [], + before_packages: [ + Newline, + ], + after_packages: [], + before_imports: [ + Newline, + ], + after_imports: [], + before_provides: [ + Newline, + ], + after_provides: [], + before_to: [], + after_to: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/full_app_header.header.roc b/compiler/parse/tests/snapshots/pass/full_app_header.header.roc new file mode 100644 index 0000000000..ce81012e75 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/full_app_header.header.roc @@ -0,0 +1,4 @@ +app "quicksort" + packages { base: "./platform" } + imports [ foo.Bar.Baz ] + provides [ quicksort ] to base diff --git a/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.result-ast b/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.result-ast new file mode 100644 index 0000000000..a6154275d6 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.result-ast @@ -0,0 +1,31 @@ +App { + header: AppHeader { + name: |L 0-0, C 4-15| PlainLine("quicksort"), + packages: [ + |L 1-1, C 15-33| Entry { shorthand: "base", spaces_after_shorthand: [], package_or_path: |L 1-1, C 21-33| Path(PlainLine("./platform")) }, + ], + imports: [ + |L 2-6, C 14-5| Package("foo", ModuleName("Bar"), Collection { items: [|L 3-3, C 8-11| SpaceBefore(Exposed("Baz"), [Newline]), |L 4-4, C 8-17| SpaceBefore(Exposed("FourtyTwo"), [Newline])], final_comments: [Newline, LineComment(" I'm a happy comment")] }), + ], + provides: [ + |L 7-7, C 15-24| Exposed("quicksort"), + ], + to: |L 7-7, C 31-35| ExistingPackage("base"), + before_header: [], + after_app_keyword: [], + before_packages: [ + Newline, + ], + after_packages: [], + before_imports: [ + Newline, + ], + after_imports: [], + before_provides: [ + Newline, + ], + after_provides: [], + before_to: [], + after_to: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.roc b/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.roc new file mode 100644 index 0000000000..30b50e51d6 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/full_app_header_trailing_commas.header.roc @@ -0,0 +1,8 @@ +app "quicksort" + packages { base: "./platform", } + imports [ foo.Bar.{ + Baz, + FourtyTwo, + # I'm a happy comment + } ] + provides [ quicksort, ] to base diff --git a/compiler/parse/tests/snapshots/pass/minimal_app_header.header.result-ast b/compiler/parse/tests/snapshots/pass/minimal_app_header.header.result-ast new file mode 100644 index 0000000000..41ea70e9f5 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/minimal_app_header.header.result-ast @@ -0,0 +1,19 @@ +App { + header: AppHeader { + name: |L 0-0, C 4-14| PlainLine("test-app"), + packages: [], + imports: [], + provides: [], + to: |L 0-0, C 30-38| NewPackage(Path(PlainLine("./blah"))), + before_header: [], + after_app_keyword: [], + before_packages: [], + after_packages: [], + before_imports: [], + after_imports: [], + before_provides: [], + after_provides: [], + before_to: [], + after_to: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/minimal_app_header.header.roc b/compiler/parse/tests/snapshots/pass/minimal_app_header.header.roc new file mode 100644 index 0000000000..4678035773 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/minimal_app_header.header.roc @@ -0,0 +1 @@ +app "test-app" provides [] to "./blah" diff --git a/compiler/parse/tests/snapshots/pass/nested_module.header.result-ast b/compiler/parse/tests/snapshots/pass/nested_module.header.result-ast new file mode 100644 index 0000000000..77fc6b1137 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/nested_module.header.result-ast @@ -0,0 +1,13 @@ +Interface { + header: InterfaceHeader { + name: |L 0-0, C 10-21| ModuleName("Foo.Bar.Baz"), + exposes: [], + imports: [], + before_header: [], + after_interface_keyword: [], + before_exposes: [], + after_exposes: [], + before_imports: [], + after_imports: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/nested_module.header.roc b/compiler/parse/tests/snapshots/pass/nested_module.header.roc new file mode 100644 index 0000000000..f43501c404 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/nested_module.header.roc @@ -0,0 +1 @@ +interface Foo.Bar.Baz exposes [] imports [] diff --git a/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.result-ast b/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.result-ast new file mode 100644 index 0000000000..dd29e16963 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.result-ast @@ -0,0 +1,51 @@ +Platform { + header: PlatformHeader { + name: |L 0-0, C 9-19| PackageName { account: "foo", pkg: "barbaz" }, + requires: PlatformRequires { + rigids: [ + |L 1-1, C 14-26| Entry { rigid: "model", alias: "Model" }, + ], + signature: |L 1-1, C 30-39| Entry { ident: |L 1-1, C 30-34| "main", spaces_before_colon: [], ann: |L 1-1, C 37-39| Record { fields: [], ext: None } }, + }, + exposes: [], + packages: [ + |L 3-3, C 15-27| Entry { shorthand: "foo", spaces_after_shorthand: [], package_or_path: |L 3-3, C 20-27| Path(PlainLine("./foo")) }, + ], + imports: [], + provides: [ + |L 5-5, C 15-26| Exposed("mainForHost"), + ], + effects: Effects { + spaces_before_effects_keyword: [ + Newline, + ], + spaces_after_effects_keyword: [], + spaces_after_type_name: [], + effect_shortname: "fx", + effect_type_name: "Effect", + entries: [], + }, + before_header: [], + after_platform_keyword: [], + before_requires: [ + Newline, + ], + after_requires: [], + before_exposes: [ + Newline, + ], + after_exposes: [], + before_packages: [ + Newline, + ], + after_packages: [], + before_imports: [ + Newline, + ], + after_imports: [], + before_provides: [ + Newline, + ], + after_provides: [], + }, +} diff --git a/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.roc b/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.roc new file mode 100644 index 0000000000..d12bc9f00a --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/nonempty_platform_header.header.roc @@ -0,0 +1,7 @@ +platform foo/barbaz + requires {model=>Model} { main : {} } + exposes [] + packages { foo: "./foo" } + imports [] + provides [ mainForHost ] + effects fx.Effect {} diff --git a/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.result-ast b/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.result-ast new file mode 100644 index 0000000000..1eae8ebab4 --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.result-ast @@ -0,0 +1,5 @@ +[ + |L 1-1, C 0-7| SpaceBefore(Body(|L 1-1, C 0-3| Identifier("foo"), |L 1-1, C 6-7| Num("1")), [LineComment(" comment 1")]), + |L 4-4, C 0-10| SpaceBefore(Body(|L 4-4, C 0-3| Identifier("bar"), |L 4-4, C 6-10| Str(PlainLine("hi"))), [Newline, Newline, LineComment(" comment 2")]), + |L 5-5, C 0-13| SpaceAfter(SpaceBefore(Body(|L 5-5, C 0-3| Identifier("baz"), |L 5-5, C 6-13| Str(PlainLine("stuff"))), [Newline]), [Newline, LineComment(" comment n")]), +] diff --git a/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.roc b/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.roc new file mode 100644 index 0000000000..2c6e02bbfd --- /dev/null +++ b/compiler/parse/tests/snapshots/pass/standalone_module_defs.module.roc @@ -0,0 +1,7 @@ +# comment 1 +foo = 1 + +# comment 2 +bar = "hi" +baz = "stuff" +# comment n diff --git a/compiler/parse/tests/test_parse.rs b/compiler/parse/tests/test_parse.rs index 1ce8f0e055..db6345ca06 100644 --- a/compiler/parse/tests/test_parse.rs +++ b/compiler/parse/tests/test_parse.rs @@ -42,11 +42,19 @@ mod test_parse { expr => { $($expr_test_name:ident),* } + header => { + $($header_test_name:ident),* + } + module => { + $($module_test_name:ident),* + } ) => { #[test] fn no_extra_snapshot_test_files() { let tests = &[ - $(concat!(stringify!($expr_test_name), ".expr")),* + $(concat!(stringify!($expr_test_name), ".expr")),*, + $(concat!(stringify!($header_test_name), ".header")),*, + $(concat!(stringify!($module_test_name), ".module")),*, ].iter().map(|t| *t).collect::>(); let mut base = std::path::PathBuf::from("tests"); @@ -67,7 +75,36 @@ mod test_parse { $( #[test] fn $expr_test_name() { - snapshot_expr_test(stringify!($expr_test_name)); + snapshot_test(stringify!($expr_test_name), "expr", |input| { + let arena = Bump::new(); + let actual_ast = parse_expr_with(&arena, input.trim()).unwrap(); + format!("{:#?}\n", actual_ast) + }); + } + )* + + $( + #[test] + fn $header_test_name() { + snapshot_test(stringify!($header_test_name), "header", |input| { + let arena = Bump::new(); + let actual_ast = roc_parse::module::parse_header(&arena, State::new(input.as_bytes())) + .map(|tuple| tuple.0).unwrap(); + format!("{:#?}\n", actual_ast) + }); + } + )* + + $( + #[test] + fn $module_test_name() { + snapshot_test(stringify!($module_test_name), "module", |input| { + let arena = Bump::new(); + let actual_ast = module_defs() + .parse(&arena, State::new(input.as_bytes())) + .map(|tuple| tuple.1).unwrap(); + format!("{:#?}\n", actual_ast) + }); } )* }; @@ -195,10 +232,22 @@ mod test_parse { zero_float, zero_int } + header => { + empty_app_header, + empty_interface_header, + empty_platform_header, + full_app_header, + full_app_header_trailing_commas, + minimal_app_header, + nested_module, + nonempty_platform_header + } + module => { + standalone_module_defs + } } - fn snapshot_expr_test(name: &str) { - let ty = "expr"; + fn snapshot_test(name: &str, ty: &str, func: impl Fn(&str) -> String) { let mut parent = std::path::PathBuf::from("tests"); parent.push("snapshots"); parent.push("pass"); @@ -208,9 +257,7 @@ mod test_parse { let input = std::fs::read_to_string(&input_path).unwrap(); let expected_result = std::fs::read_to_string(&result_path).unwrap(); - let arena = Bump::new(); - let actual_ast = parse_expr_with(&arena, input.trim()).unwrap(); - let actual_result = format!("{:#?}\n", actual_ast); + let actual_result = func(&input); if std::env::var("ROC_PARSER_SNAPSHOT_TEST_OVERWRITE").is_ok() { std::fs::write(&result_path, actual_result).unwrap(); @@ -788,467 +835,6 @@ mod test_parse { // ); // } - // MODULE - - #[test] - fn empty_app_header() { - let arena = Bump::new(); - let packages = Collection::empty(); - let imports = Collection::empty(); - let provides = Collection::empty(); - let module_name = StrLiteral::PlainLine("test-app"); - let header = AppHeader { - name: Located::new(0, 0, 4, 14, module_name), - packages, - imports, - provides, - to: Located::new(0, 0, 53, 57, To::ExistingPackage("blah")), - before_header: &[], - after_app_keyword: &[], - before_packages: &[], - after_packages: &[], - before_imports: &[], - after_imports: &[], - before_provides: &[], - after_provides: &[], - before_to: &[], - after_to: &[], - }; - - let expected = roc_parse::ast::Module::App { header }; - - let src = indoc!( - r#" - app "test-app" packages {} imports [] provides [] to blah - "# - ); - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn minimal_app_header() { - use PackageOrPath::Path; - - let arena = Bump::new(); - let packages = Collection::empty(); - let imports = Collection::empty(); - let provides = Collection::empty(); - let module_name = StrLiteral::PlainLine("test-app"); - let header = AppHeader { - before_header: &[], - name: Located::new(0, 0, 4, 14, module_name), - packages, - imports, - provides, - to: Located::new(0, 0, 30, 38, To::NewPackage(Path(PlainLine("./blah")))), - after_app_keyword: &[], - before_packages: &[], - after_packages: &[], - before_imports: &[], - after_imports: &[], - before_provides: &[], - after_provides: &[], - before_to: &[], - after_to: &[], - }; - - let expected = roc_parse::ast::Module::App { header }; - - let src = indoc!( - r#" - app "test-app" provides [] to "./blah" - "# - ); - - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn full_app_header() { - use ExposesEntry::Exposed; - use PackageOrPath::Path; - - let newlines = &[Newline]; - let pkg_entry = PackageEntry::Entry { - shorthand: "base", - spaces_after_shorthand: &[], - package_or_path: Located::new(1, 1, 21, 33, Path(PlainLine("./platform"))), - }; - let loc_pkg_entry = Located::new(1, 1, 15, 33, pkg_entry); - let arena = Bump::new(); - let packages = Collection::with_items(arena.alloc([loc_pkg_entry])); - let import = ImportsEntry::Package("foo", ModuleName::new("Bar.Baz"), Collection::empty()); - let loc_import = Located::new(2, 2, 14, 25, import); - let imports = Collection::with_items(arena.alloc([loc_import])); - let provide_entry = Located::new(3, 3, 15, 24, Exposed("quicksort")); - let provides = Collection::with_items(arena.alloc([provide_entry])); - let module_name = StrLiteral::PlainLine("quicksort"); - - let header = AppHeader { - before_header: &[], - name: Located::new(0, 0, 4, 15, module_name), - packages, - imports, - provides, - to: Located::new(3, 3, 30, 34, To::ExistingPackage("base")), - after_app_keyword: &[], - before_packages: newlines, - after_packages: &[], - before_imports: newlines, - after_imports: &[], - before_provides: newlines, - after_provides: &[], - before_to: &[], - after_to: &[], - }; - - let expected = roc_parse::ast::Module::App { header }; - - let src = indoc!( - r#" - app "quicksort" - packages { base: "./platform" } - imports [ foo.Bar.Baz ] - provides [ quicksort ] to base - "# - ); - - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn full_app_header_trailing_commas() { - use ExposesEntry::Exposed; - use PackageOrPath::Path; - - let newlines = &[Newline]; - let pkg_entry = PackageEntry::Entry { - shorthand: "base", - spaces_after_shorthand: &[], - package_or_path: Located::new(1, 1, 21, 33, Path(PlainLine("./platform"))), - }; - let loc_pkg_entry = Located::new(1, 1, 15, 33, pkg_entry); - let arena = Bump::new(); - let packages = Collection::with_items(arena.alloc([loc_pkg_entry])); - let import = ImportsEntry::Package( - "foo", - ModuleName::new("Bar"), - Collection::with_items_and_comments( - &arena, - arena.alloc([ - Located::new( - 3, - 3, - 8, - 11, - ExposesEntry::SpaceBefore( - arena.alloc(ExposesEntry::Exposed("Baz")), - arena.alloc([Newline]), - ), - ), - Located::new( - 4, - 4, - 8, - 17, - ExposesEntry::SpaceBefore( - arena.alloc(ExposesEntry::Exposed("FourtyTwo")), - arena.alloc([Newline]), - ), - ), - ]), - arena.alloc([Newline, LineComment(" I'm a happy comment")]), - ), - ); - let loc_import = Located::new(2, 6, 14, 5, import); - let imports = Collection::with_items(arena.alloc([loc_import])); - let provide_entry = Located::new(7, 7, 15, 24, Exposed("quicksort")); - let provides = Collection::with_items(arena.alloc([provide_entry])); - let module_name = StrLiteral::PlainLine("quicksort"); - - let header = AppHeader { - before_header: &[], - name: Located::new(0, 0, 4, 15, module_name), - packages, - imports, - provides, - to: Located::new(7, 7, 31, 35, To::ExistingPackage("base")), - after_app_keyword: &[], - before_packages: newlines, - after_packages: &[], - before_imports: newlines, - after_imports: &[], - before_provides: newlines, - after_provides: &[], - before_to: &[], - after_to: &[], - }; - - let expected = roc_parse::ast::Module::App { header }; - - let src = indoc!( - r#" - app "quicksort" - packages { base: "./platform", } - imports [ foo.Bar.{ - Baz, - FourtyTwo, - # I'm a happy comment - } ] - provides [ quicksort, ] to base - "# - ); - - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn empty_platform_header() { - let pkg_name = PackageName { - account: "rtfeldman", - pkg: "blah", - }; - let arena = Bump::new(); - let effects = Effects { - effect_type_name: "Blah", - effect_shortname: "fx", - entries: &[], - spaces_before_effects_keyword: &[], - spaces_after_effects_keyword: &[], - spaces_after_type_name: &[], - }; - - let requires = { - let region1 = Region::new(0, 0, 38, 47); - let region2 = Region::new(0, 0, 45, 47); - - PlatformRequires { - rigids: Collection::empty(), - signature: Located::at( - region1, - TypedIdent::Entry { - ident: Located::new(0, 0, 38, 42, "main"), - spaces_before_colon: &[], - ann: Located::at( - region2, - TypeAnnotation::Record { - fields: Collection::empty(), - ext: None, - }, - ), - }, - ), - } - }; - - let header = PlatformHeader { - before_header: &[], - name: Located::new(0, 0, 9, 23, pkg_name), - requires, - exposes: Collection::empty(), - packages: Collection::empty(), - imports: Collection::empty(), - provides: Collection::empty(), - effects, - after_platform_keyword: &[], - before_requires: &[], - after_requires: &[], - before_exposes: &[], - after_exposes: &[], - before_packages: &[], - after_packages: &[], - before_imports: &[], - after_imports: &[], - before_provides: &[], - after_provides: &[], - }; - - let expected = roc_parse::ast::Module::Platform { header }; - - let src = "platform rtfeldman/blah requires {} { main : {} } exposes [] packages {} imports [] provides [] effects fx.Blah {}"; - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn nonempty_platform_header() { - use ExposesEntry::Exposed; - use PackageOrPath::Path; - - let newlines = &[Newline]; - let pkg_name = PackageName { - account: "foo", - pkg: "barbaz", - }; - let pkg_entry = PackageEntry::Entry { - shorthand: "foo", - spaces_after_shorthand: &[], - package_or_path: Located::new(3, 3, 20, 27, Path(PlainLine("./foo"))), - }; - let loc_pkg_entry = Located::new(3, 3, 15, 27, pkg_entry); - let arena = Bump::new(); - let packages = Collection::with_items(arena.alloc([loc_pkg_entry])); - let imports = Collection::empty(); - let provide_entry = Located::new(5, 5, 15, 26, Exposed("mainForHost")); - let provides = Collection::with_items(arena.alloc([provide_entry])); - let effects = Effects { - effect_type_name: "Effect", - effect_shortname: "fx", - entries: &[], - spaces_before_effects_keyword: newlines, - spaces_after_effects_keyword: &[], - spaces_after_type_name: &[], - }; - - let requires = { - let region1 = Region::new(1, 1, 30, 39); - let region2 = Region::new(1, 1, 37, 39); - let region3 = Region::new(1, 1, 14, 26); - - PlatformRequires { - rigids: Collection::with_items(arena.alloc([Located::at( - region3, - PlatformRigid::Entry { - alias: "Model", - rigid: "model", - }, - )])), - signature: Located::at( - region1, - TypedIdent::Entry { - ident: Located::new(1, 1, 30, 34, "main"), - spaces_before_colon: &[], - ann: Located::at( - region2, - TypeAnnotation::Record { - fields: Collection::empty(), - ext: None, - }, - ), - }, - ), - } - }; - - let header = PlatformHeader { - before_header: &[], - name: Located::new(0, 0, 9, 19, pkg_name), - requires, - exposes: Collection::empty(), - packages, - imports, - provides, - effects, - after_platform_keyword: &[], - before_requires: newlines, - after_requires: &[], - before_exposes: newlines, - after_exposes: &[], - before_packages: newlines, - after_packages: &[], - before_imports: newlines, - after_imports: &[], - before_provides: newlines, - after_provides: &[], - }; - - let expected = roc_parse::ast::Module::Platform { header }; - - let src = indoc!( - r#" - platform foo/barbaz - requires {model=>Model} { main : {} } - exposes [] - packages { foo: "./foo" } - imports [] - provides [ mainForHost ] - effects fx.Effect {} - "# - ); - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn empty_interface_header() { - let arena = Bump::new(); - let exposes = Collection::empty(); - let imports = Collection::empty(); - let module_name = ModuleName::new("Foo"); - let header = InterfaceHeader { - before_header: &[], - name: Located::new(0, 0, 10, 13, module_name), - exposes, - imports, - - after_interface_keyword: &[], - before_exposes: &[], - after_exposes: &[], - before_imports: &[], - after_imports: &[], - }; - - let expected = roc_parse::ast::Module::Interface { header }; - - let src = indoc!( - r#" - interface Foo exposes [] imports [] - "# - ); - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - - #[test] - fn nested_module() { - let arena = Bump::new(); - let exposes = Collection::empty(); - let imports = Collection::empty(); - let module_name = ModuleName::new("Foo.Bar.Baz"); - let header = InterfaceHeader { - before_header: &[], - name: Located::new(0, 0, 10, 21, module_name), - exposes, - imports, - - after_interface_keyword: &[], - before_exposes: &[], - after_exposes: &[], - before_imports: &[], - after_imports: &[], - }; - - let expected = roc_parse::ast::Module::Interface { header }; - - let src = indoc!( - r#" - interface Foo.Bar.Baz exposes [] imports [] - "# - ); - let actual = roc_parse::module::parse_header(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.0); - - assert_eq!(Ok(expected), actual); - } - #[test] fn repro_keyword_bug() { // Reproducing this bug requires a bizarre set of things to all be true: @@ -1280,64 +866,6 @@ mod test_parse { assert_eq!(occurrences, 2); } - #[test] - fn standalone_module_defs() { - use Def::*; - - let arena = Bump::new(); - let pattern1 = Identifier("foo"); - let pattern2 = Identifier("bar"); - let pattern3 = Identifier("baz"); - let def1 = SpaceBefore( - arena.alloc(Body( - arena.alloc(Located::new(1, 1, 0, 3, pattern1)), - arena.alloc(Located::new(1, 1, 6, 7, Num("1"))), - )), - &[LineComment(" comment 1")], - ); - let def2 = SpaceBefore( - arena.alloc(Body( - arena.alloc(Located::new(4, 4, 0, 3, pattern2)), - arena.alloc(Located::new(4, 4, 6, 10, Str(PlainLine("hi")))), - )), - &[Newline, Newline, LineComment(" comment 2")], - ); - let def3 = SpaceAfter( - arena.alloc(SpaceBefore( - arena.alloc(Body( - arena.alloc(Located::new(5, 5, 0, 3, pattern3)), - arena.alloc(Located::new(5, 5, 6, 13, Str(PlainLine("stuff")))), - )), - &[Newline], - )), - &[Newline, LineComment(" comment n")], - ); - - let expected = bumpalo::vec![in &arena; - Located::new(1,1, 0, 7, def1), - Located::new(4,4, 0, 10, def2), - Located::new(5,5, 0, 13, def3), - ]; - - let src = indoc!( - r#" - # comment 1 - foo = 1 - - # comment 2 - bar = "hi" - baz = "stuff" - # comment n - "# - ); - - let actual = module_defs() - .parse(&arena, State::new(src.as_bytes())) - .map(|tuple| tuple.1); - - assert_eq!(Ok(expected), actual); - } - #[test] fn module_def_newline() { let arena = Bump::new();