mvdan / gofumpt

A stricter gofmt
https://pkg.go.dev/mvdan.cc/gofumpt
BSD 3-Clause "New" or "Revised" License
3.15k stars 110 forks source link

feature: Enforce line breaks between multiline function calls with func() argument #290

Open Limero opened 6 months ago

Limero commented 6 months ago

At work we often use t.Run() inside of test cases to separate parts of it, but there is no consistency to the line breaks separating these, so our tests often end up looking like this:

t.Run("a", func(t *testing.T) {
    //
})
t.Run("b", func(t *testing.T) {
    //
})

t.Run("c", func(t *testing.T) {
    //
})

It would be useful if gofumpt enforced the linebreaks between multiline function calls with func() as argument.

When a function is passed as an argument, it basically becomes a wrapper around a stand-alone function, so rules similar to the existing "Multiline top-level declarations must be separated by empty lines" rule should be applied.

Expected result:

t.Run("a", func(t *testing.T) {
    //
})

t.Run("b", func(t *testing.T) {
    //
})

t.Run("c", func(t *testing.T) {
    //
})
mvdan commented 5 months ago

Thanks for filing this issue. I can see how you might want consistency when empty lines are used between some t.Run calls and not others, but I honestly don't think either approach (all use empty lines in between, versus none use empty lines in between) is clearly the canonical formatting that everyone should use.

For example, https://github.com/cue-labs/oci/blob/14751940d5b22f24e01c024cc61a3138565f8c7e/ociregistry/internal/conformance/conformance_test.go#L131-L139 seems perfectly fine to me, as does https://github.com/go-json-experiment/json/blob/2e55bd4e08b08427ba10066e9617338e1f113c53/jsontext/coder_test.go#L704-L753, which also seems to group subtest functions based on the categories.

All in all, I don't think we can enforce anything like this in general.