cweill / gotests

Automatically generate Go test boilerplate from your source code.
Apache License 2.0
4.95k stars 345 forks source link

Generic function support #165

Open suzmue opened 2 years ago

suzmue commented 2 years ago

Filing this issue to track/ discuss generic function support for gotests.

Currently, gotests produces a table driven test for a function with type parameters, but the test needs to actually be modified to include concrete types (the test file will have build errors).

Example:

typeparams.go:

package typeparams

// SumIntsOrFloats sums the values of map m. It supports both floats and integers
// as map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}

typeparams_test.go:

package typeparams

import (
    "reflect"
    "testing"
)

func TestSumIntsOrFloats(t *testing.T) {
    type args struct {
        m map[K]V // K and V not defined
    }
    tests := []struct {
        name string
        args args
        want V
    }{
        // TODO: Add test cases.
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := SumIntsOrFloats(tt.args.m); !reflect.DeepEqual(got, tt.want) {
                t.Errorf("SumIntsOrFloats() = %v, want %v", got, tt.want)
            }
        })
    }
}

Can better table driven tests be generated for functions with type params / should the generated tests make sure there are no build errors?

Related go issue: golang/go#50558

KevinSnyderCodes commented 2 years ago

For some inputs, gotests fails to generate tests:

typeparams.go

package typeparams

type Set[T comparable] struct {
    m map[T]struct{}
}

func (o *Set[T]) Add(v T) {
    o.m[v] = struct{}{}
}

func (o *Set[T]) Has(v T) bool {
    _, ok := o.m[v]
    return ok
}

gotests output:

output.Process: imports.Process: /var/folders/fw/grysx2h56354vh4_30px6_r80000gp/T/gotests_112301585:9:14: all type parameters must be named (and 1 more errors)