Fork of daniellemaywood.uk/gleam — Wasm codegen work
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2023 The Gleam contributors
3
4use crate::{assert_format, assert_format_rewrite};
5
6#[test]
7fn capture_with_single_argument() {
8 assert_format_rewrite!(
9 "pub fn main() -> Nil {
10 wibble([], wobble(_))
11}
12",
13 "pub fn main() -> Nil {
14 wibble([], wobble)
15}
16"
17 );
18}
19
20#[test]
21fn deprecated() {
22 assert_format!(
23 r#"@deprecated("use something else instead")
24pub fn main() -> Nil {
25 Nil
26}
27"#
28 );
29}
30
31#[test]
32fn deprecated_external() {
33 assert_format!(
34 r#"@deprecated("use something else instead")
35@external(erlang, "thing", "main")
36pub fn main() -> Nil
37"#
38 );
39}
40
41#[test]
42fn anonymous_function_as_final_function_argument() {
43 assert_format!(
44 r#"pub fn main() {
45 some_function(123, 456, fn(x) {
46 let y = x + 1
47 y
48 })
49}
50"#
51 );
52}
53
54#[test]
55fn anonymous_function_with_single_line_body_as_final_function_argument() {
56 assert_format!(
57 r#"pub fn main() {
58 some_function(123, 456, fn(x) { x })
59}
60"#
61 );
62}
63
64#[test]
65fn anonymous_function_with_multi_line_unbreakable_body_as_final_function_argument() {
66 assert_format!(
67 r#"pub fn main() {
68 some_function(123, 456, fn(x) {
69 call_to_other_function(a, b, c, d, e, f, g, h)
70 })
71}
72"#
73 );
74}
75
76#[test]
77fn anonymous_function_with_multi_line_breakable_body_as_final_function_argument() {
78 assert_format!(
79 r#"pub fn main() {
80 some_function(123, 456, fn(x) {
81 call_to_other_function(a, b, c, d, e, f, g, { x + x })
82 })
83}
84"#
85 );
86}
87
88#[test]
89fn anonymous_function_with_multi_line_long_breakable_body_as_final_function_argument() {
90 assert_format!(
91 r#"pub fn main() {
92 some_function(123, 456, fn(x) {
93 call_to_other_function(a, b, c, d, e, f, g, case wibble {
94 Wibble -> 1
95 Wobble -> 2
96 })
97 })
98}
99"#
100 );
101}
102
103#[test]
104fn function_call_as_final_function_argument_goes_on_its_own_line() {
105 assert_format!(
106 r#"pub fn main() {
107 some_function_with_a_long_name(
108 123,
109 456,
110 another_function_being_called(123, 456),
111 )
112}
113"#
114 );
115}
116
117#[test]
118fn tuple_as_final_function_argument() {
119 assert_format!(
120 r#"pub fn main() {
121 some_function(123, 456, #(
122 "Here is a very long string which causes the formatter to wrap it",
123 ))
124}
125"#
126 );
127}
128
129#[test]
130fn list_as_final_function_argument() {
131 assert_format!(
132 r#"pub fn main() {
133 some_function(123, 456, [
134 "Here is a very long string which causes the formatter to wrap it",
135 ])
136}
137"#
138 );
139}
140
141#[test]
142fn case_expression_as_final_function_argument() {
143 assert_format!(
144 r#"pub fn main() {
145 some_function(123, 456, case my_var {
146 True -> True
147 False -> False
148 })
149}
150"#
151 );
152}
153
154#[test]
155fn block_as_final_function_argument() {
156 assert_format!(
157 r#"pub fn main() {
158 some_function(123, 456, {
159 let days = 7
160 days * 24 * 60 * 60
161 })
162}
163"#
164 );
165}
166
167#[test]
168fn when_all_arguments_are_too_long_each_one_is_on_its_own_line() {
169 assert_format!(
170 r#"pub fn main() {
171 some_function(
172 variable_with_really_long_name,
173 whoah_this_is_getting_out_of_hand,
174 ["Here is a very long string which causes the formatter to wrap it"],
175 )
176}
177"#
178 );
179}
180
181#[test]
182fn nested_breakable_lists_in_function_calls() {
183 assert_format!(
184 r#"pub fn main() {
185 html([attribute("lang", "en")], [
186 head([attribute("wibble", "wobble")], [
187 title([], [text("Hello this is some HTML")]),
188 ]),
189 body([], [h1([], [text("Hello, world!")])]),
190 ])
191}
192"#
193 );
194}
195
196#[test]
197fn nested_breakable_tuples_in_function_calls() {
198 assert_format!(
199 r#"pub fn main() {
200 html(#(attribute("lang", "en")), #(
201 head(#(attribute("wibble", "wobble")), #(
202 title(#(), #(text("Hello this is some HTML"))),
203 body(#(), #(text("Hello this is some HTML"))),
204 )),
205 body(#(), #(h1(#(), #(text("Hello, lisp!"))))),
206 ))
207}
208"#
209 );
210}
211
212// https://github.com/gleam-lang/gleam/issues/2435
213#[test]
214fn only_last_argument_can_be_broken() {
215 assert_format!(
216 r#"pub fn main() {
217 tbd.workbook(for: "my_project")
218 |> task(
219 doc: "Run the project tests",
220 tags: list.concat([["test", "ci"], gleam, typescript]),
221 action: fn(_, _) { tbd.command(run: "gleam", with: ["test"]) },
222 )
223 |> run
224}
225"#
226 );
227
228 assert_format!(
229 r#"pub fn main() {
230 Theme(
231 flag: styler([32]),
232 heading: styler([1, 95]),
233 highlight: styler([1, 36]),
234 parameter: styler([34]),
235 tag: styler([33]),
236 given_tag: styler([3]),
237 first_tag: styler([1]),
238 tab: " ",
239 )
240}
241"#
242 );
243}
244
245#[test]
246fn function_that_is_a_little_over_the_limit() {
247 assert_format!(
248 r#"pub fn handle_request(
249 handler: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
250) -> Nil {
251 todo
252}
253"#
254 );
255}
256
257// https://github.com/gleam-lang/gleam/issues/2571
258#[test]
259fn expr_function_as_last_argument() {
260 assert_format!(
261 r#"pub fn main() {
262 Builder(
263 accumulator: "",
264 update: fn(accum, val) { accum <> val },
265 final: fn(accum) { accum },
266 )
267}
268"#
269 );
270
271 // We want to make sure that, if it goes over the limit NOT with its
272 // arguments' list the body is still the first thing that gets split.
273 assert_format!(
274 r#"pub fn main() {
275 Builder(accumulator: "", update: fn(accum, val) { accum }, final: fn(accum) {
276 accum
277 })
278}
279"#
280 );
281}
282
283#[test]
284fn comment_at_start_of_inline_function_body() {
285 assert_format!(
286 r#"pub fn main() {
287 let add = fn(x: Int, y: Int) {
288 // This is a comment
289 x + y
290 }
291}
292"#
293 );
294}
295
296#[test]
297fn comment_at_start_of_top_level_function_body() {
298 assert_format!(
299 r#"pub fn add(x: Int, y: Int) {
300 // This is a comment
301 x + y
302}
303"#
304 );
305}
306
307#[test]
308fn comment_at_end_of_inline_function_args() {
309 assert_format!(
310 r#"pub fn main() {
311 let add = fn(
312 x: Int,
313 y: Int,
314 // This is a comment
315 ) {
316 x + y
317 }
318}
319"#
320 );
321}
322
323#[test]
324fn comment_middle_of_inline_function_body() {
325 assert_format!(
326 r#"pub fn main() {
327 let add = fn(x: Int, y: Int, z: Int) {
328 let a = x + y
329 // This is a comment
330 a + z
331 }
332}
333"#
334 );
335}
336
337// https://github.com/gleam-lang/gleam/issues/5004
338#[test]
339fn comment_in_tuple_return_type() {
340 assert_format_rewrite!(
341 r#"pub fn main() -> #(
342 // This is a string
343 String, // This is an awesome string
344) {
345 todo
346}
347"#,
348 r#"pub fn main() -> #(
349 // This is a string
350 String,
351 // This is an awesome string
352) {
353 todo
354}
355"#
356 );
357}
358
359// https://github.com/gleam-lang/gleam/issues/5225
360#[test]
361fn comments_between_function_params() {
362 assert_format!(
363 r#"pub fn main(
364 // a function with argument comments
365 a: fn(
366 // Int,
367 String,
368 Int,
369 // this is A
370 String,
371 // this is B
372 String,
373 fn(
374 // an inner fn, fn arg
375 Int,
376 // trailing comment
377 ) -> String,
378 // multiple lines
379 // for a really interesting
380 // comment
381 Bool,
382 // trailing comment
383 ) -> Nil,
384 // a function with no argument comments
385 b: fn(Int) -> Nil,
386 c: fn() -> Nil,
387) {
388 todo
389}
390"#
391 );
392}
393
394#[test]
395fn long_function_slightly_over_80_chars_gets_broken() {
396 assert_format_rewrite!(
397 "
398fn do_menu_items(acc: Queue(MenuItem), from tasks: List(Task)) -> List(MenuItem) {
399 todo
400}
401",
402 "fn do_menu_items(
403 acc: Queue(MenuItem),
404 from tasks: List(Task),
405) -> List(MenuItem) {
406 todo
407}
408"
409 );
410}