mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Merge 67c3f3a617 into 4d0abeb37c
This commit is contained in:
commit
8d19dfdecf
6 changed files with 259 additions and 178 deletions
|
|
@ -1,19 +1,35 @@
|
|||
package binding_test
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/float_package"
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/int_package"
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/map_package"
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/uint_package"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
const expectedBindings = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
type HandlerTest struct{}
|
||||
|
||||
func (h *HandlerTest) StartingWithInt(_ int_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithFloat(_ float_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithUint(_ uint_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithMap(_ map_package.SomeStruct) {}
|
||||
|
||||
func (h *HandlerTest) Get() HandlerTest {
|
||||
return *h
|
||||
}
|
||||
|
||||
var ConflictingPackageNameTest = BindingTest{
|
||||
name: "ConflictingPackageNameTest",
|
||||
structs: []interface{}{
|
||||
&HandlerTest{},
|
||||
&float_package.SomeStruct{},
|
||||
&int_package.SomeStruct{},
|
||||
&map_package.SomeStruct{},
|
||||
&uint_package.SomeStruct{},
|
||||
},
|
||||
exemptions: nil,
|
||||
shouldError: false,
|
||||
want: `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {float_package} from '../models';
|
||||
import {int_package} from '../models';
|
||||
|
|
@ -27,38 +43,5 @@ export function StartingWithInt(arg1:int_package.SomeStruct):Promise<void>;
|
|||
export function StartingWithMap(arg1:map_package.SomeStruct):Promise<void>;
|
||||
|
||||
export function StartingWithUint(arg1:uint_package.SomeStruct):Promise<void>;
|
||||
`
|
||||
|
||||
type HandlerTest struct{}
|
||||
|
||||
func (h *HandlerTest) StartingWithInt(_ int_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithFloat(_ float_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithUint(_ uint_package.SomeStruct) {}
|
||||
func (h *HandlerTest) StartingWithMap(_ map_package.SomeStruct) {}
|
||||
|
||||
func TestConflictingPackageName(t *testing.T) {
|
||||
// given
|
||||
generationDir := t.TempDir()
|
||||
|
||||
// setup
|
||||
testLogger := &logger.Logger{}
|
||||
b := binding.NewBindings(testLogger, []interface{}{&HandlerTest{}}, []interface{}{}, false, []interface{}{})
|
||||
|
||||
// then
|
||||
err := b.GenerateGoBindings(generationDir)
|
||||
if err != nil {
|
||||
t.Fatalf("could not generate the Go bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
rawGeneratedBindings, err := fs.ReadFile(os.DirFS(generationDir), "binding_test/HandlerTest.d.ts")
|
||||
if err != nil {
|
||||
t.Fatalf("could not read the generated bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
generatedBindings := string(rawGeneratedBindings)
|
||||
if generatedBindings != expectedBindings {
|
||||
t.Fatalf("the generated bindings does not match the expected ones.\nWanted:\n%s\n\nGot:\n%s", expectedBindings, generatedBindings)
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
|
|
|||
41
v2/internal/binding/binding_test/binding_custom_type_test.go
Normal file
41
v2/internal/binding/binding_test/binding_custom_type_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package binding_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type CustomTypeStruct struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
func (s CustomTypeStruct) Get() CustomTypeStruct {
|
||||
return s
|
||||
}
|
||||
|
||||
var CustomTypeGenerationTest = BindingTest{
|
||||
name: "CustomTypeGenerationTest",
|
||||
structs: []interface{}{
|
||||
&CustomTypeStruct{},
|
||||
},
|
||||
exemptions: nil,
|
||||
shouldError: false,
|
||||
want: `
|
||||
export namespace binding_test {
|
||||
export class CustomTypeStruct {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
static createFrom(source: any = {}) {
|
||||
return new CustomTypeStruct(source);
|
||||
}
|
||||
constructor(source: any = {}) {
|
||||
if ('string' === typeof source) source = JSON.parse(source);
|
||||
this.id = source["id"];
|
||||
this.createdAt = source["createdAt"];
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
|
@ -1,15 +1,41 @@
|
|||
package binding_test
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
// Define the Go types to be tested
|
||||
type PromisesTest struct{}
|
||||
type PromisesTestReturnStruct struct{}
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
// Methods returning different types to exercise promise handling
|
||||
func (h *PromisesTest) NoReturn(_ string) {}
|
||||
func (h *PromisesTest) ErrorReturn(_ int) error { return nil }
|
||||
func (h *PromisesTest) SingleReturn(_ interface{}) int { return 0 }
|
||||
func (h *PromisesTest) SingleReturnStruct(_ interface{}) PromisesTestReturnStruct {
|
||||
return PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStructPointer(_ interface{}) *PromisesTestReturnStruct {
|
||||
return &PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStructSlice(_ interface{}) []PromisesTestReturnStruct {
|
||||
return []PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStructPointerSlice(_ interface{}) []*PromisesTestReturnStruct {
|
||||
return []*PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnWithError(_ int) (string, error) { return "", nil }
|
||||
func (h *PromisesTest) TwoReturn(_ interface{}) (string, int) { return "", 0 }
|
||||
|
||||
const expectedPromiseBindings = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// Optional Get() method for consistency with other tests
|
||||
func (h *PromisesTest) Get() PromisesTest { return *h }
|
||||
|
||||
// The test definition recognized by TestBindings_GenerateModels
|
||||
var PromisesBindingTest = BindingTest{
|
||||
name: "PromisesBindingTest",
|
||||
structs: []interface{}{
|
||||
&PromisesTest{},
|
||||
&PromisesTestReturnStruct{},
|
||||
},
|
||||
exemptions: nil,
|
||||
shouldError: false,
|
||||
want: `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {binding_test} from '../models';
|
||||
|
||||
|
|
@ -30,52 +56,5 @@ export function SingleReturnStructSlice(arg1:any):Promise<Array<binding_test.Pro
|
|||
export function SingleReturnWithError(arg1:number):Promise<string>;
|
||||
|
||||
export function TwoReturn(arg1:any):Promise<string|number>;
|
||||
`
|
||||
|
||||
type PromisesTest struct{}
|
||||
type PromisesTestReturnStruct struct{}
|
||||
|
||||
func (h *PromisesTest) NoReturn(_ string) {}
|
||||
func (h *PromisesTest) ErrorReturn(_ int) error { return nil }
|
||||
func (h *PromisesTest) SingleReturn(_ interface{}) int { return 0 }
|
||||
func (h *PromisesTest) SingleReturnStructPointer(_ interface{}) *PromisesTestReturnStruct {
|
||||
return &PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStruct(_ interface{}) PromisesTestReturnStruct {
|
||||
return PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStructSlice(_ interface{}) []PromisesTestReturnStruct {
|
||||
return []PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnStructPointerSlice(_ interface{}) []*PromisesTestReturnStruct {
|
||||
return []*PromisesTestReturnStruct{}
|
||||
}
|
||||
func (h *PromisesTest) SingleReturnWithError(_ int) (string, error) { return "", nil }
|
||||
func (h *PromisesTest) TwoReturn(_ interface{}) (string, int) { return "", 0 }
|
||||
|
||||
func TestPromises(t *testing.T) {
|
||||
// given
|
||||
generationDir := t.TempDir()
|
||||
|
||||
// setup
|
||||
testLogger := &logger.Logger{}
|
||||
b := binding.NewBindings(testLogger, []interface{}{&PromisesTest{}}, []interface{}{}, false, []interface{}{})
|
||||
|
||||
// then
|
||||
err := b.GenerateGoBindings(generationDir)
|
||||
if err != nil {
|
||||
t.Fatalf("could not generate the Go bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
rawGeneratedBindings, err := fs.ReadFile(os.DirFS(generationDir), "binding_test/PromisesTest.d.ts")
|
||||
if err != nil {
|
||||
t.Fatalf("could not read the generated bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
generatedBindings := string(rawGeneratedBindings)
|
||||
if generatedBindings != expectedPromiseBindings {
|
||||
t.Fatalf("the generated bindings does not match the expected ones.\nWanted:\n%s\n\nGot:\n%s", expectedPromiseBindings, generatedBindings)
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,36 @@ package binding_test
|
|||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding/binding_test/binding_test_import/int_package"
|
||||
"io/fs"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
||||
const expectedTypeAliasBindings = `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
type AliasTest struct{}
|
||||
type MapAlias map[string]string
|
||||
|
||||
func (h *AliasTest) Map() map[string]string { return nil }
|
||||
func (h *AliasTest) MapAlias() MapAlias { return nil }
|
||||
func (h *AliasTest) MapWithImportedStructValue() map[string]int_package.SomeStruct {
|
||||
return nil
|
||||
}
|
||||
func (h *AliasTest) Slice() []string { return nil }
|
||||
func (h *AliasTest) SliceImportedStruct() []int_package.SomeStruct {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Optional, to match other canonical binding tests
|
||||
func (h *AliasTest) Get() AliasTest {
|
||||
return *h
|
||||
}
|
||||
|
||||
var TypeAliasTest = BindingTest{
|
||||
name: "TypeAliasTest",
|
||||
structs: []interface{}{
|
||||
&AliasTest{},
|
||||
&MapAlias{},
|
||||
&int_package.SomeStruct{},
|
||||
},
|
||||
exemptions: nil,
|
||||
shouldError: false,
|
||||
want: `// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
import {binding_test} from '../models';
|
||||
import {int_package} from '../models';
|
||||
|
|
@ -24,41 +45,5 @@ export function MapWithImportedStructValue():Promise<Record<string, int_package.
|
|||
export function Slice():Promise<Array<string>>;
|
||||
|
||||
export function SliceImportedStruct():Promise<Array<int_package.SomeStruct>>;
|
||||
`
|
||||
|
||||
type AliasTest struct{}
|
||||
type MapAlias map[string]string
|
||||
|
||||
func (h *AliasTest) Map() map[string]string { return nil }
|
||||
func (h *AliasTest) MapAlias() MapAlias { return nil }
|
||||
func (h *AliasTest) MapWithImportedStructValue() map[string]int_package.SomeStruct { return nil }
|
||||
func (h *AliasTest) Slice() []string { return nil }
|
||||
func (h *AliasTest) SliceImportedStruct() []int_package.SomeStruct { return nil }
|
||||
|
||||
func TestAliases(t *testing.T) {
|
||||
// given
|
||||
generationDir := t.TempDir()
|
||||
|
||||
// setup
|
||||
testLogger := &logger.Logger{}
|
||||
b := binding.NewBindings(testLogger, []interface{}{&AliasTest{}}, []interface{}{}, false, []interface{}{})
|
||||
|
||||
// then
|
||||
err := b.GenerateGoBindings(generationDir)
|
||||
if err != nil {
|
||||
t.Fatalf("could not generate the Go bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
rawGeneratedBindings, err := fs.ReadFile(os.DirFS(generationDir), "binding_test/AliasTest.d.ts")
|
||||
if err != nil {
|
||||
t.Fatalf("could not read the generated bindings: %v", err)
|
||||
}
|
||||
|
||||
// then
|
||||
generatedBindings := string(rawGeneratedBindings)
|
||||
if generatedBindings != expectedTypeAliasBindings {
|
||||
t.Fatalf("the generated bindings does not match the expected ones.\nWanted:\n%s\n\nGot:\n%s", expectedTypeAliasBindings,
|
||||
generatedBindings)
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,9 +145,20 @@ func (b *Bindings) GenerateGoBindings(baseDir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var customTypeMap = map[string]string{
|
||||
"time.Time": "string",
|
||||
"url.URL": "string",
|
||||
"uuid.UUID": "string",
|
||||
}
|
||||
|
||||
func fullyQualifiedName(packageName string, typeName string) string {
|
||||
fullType := typeName
|
||||
if len(packageName) > 0 {
|
||||
return packageName + "." + typeName
|
||||
fullType = packageName + "." + typeName
|
||||
}
|
||||
|
||||
if tsType, ok := customTypeMap[fullType]; ok {
|
||||
return tsType
|
||||
}
|
||||
|
||||
switch true {
|
||||
|
|
@ -173,6 +184,7 @@ func fullyQualifiedName(packageName string, typeName string) string {
|
|||
|
||||
var (
|
||||
jsVariableUnsafeChars = regexp.MustCompile(`[^A-Za-z0-9_]`)
|
||||
genericTypePattern = regexp.MustCompile(`^(.*)\[(.*)\]$`)
|
||||
)
|
||||
|
||||
func arrayifyValue(valueArray string, valueType string) string {
|
||||
|
|
@ -190,52 +202,105 @@ func arrayifyValue(valueArray string, valueType string) string {
|
|||
return "Array<" + valueType + ">"
|
||||
}
|
||||
|
||||
func goTypeToJSDocType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
matches := mapRegex.FindStringSubmatch(input)
|
||||
keyPackage := matches[keyPackageIndex]
|
||||
keyType := matches[keyTypeIndex]
|
||||
valueArray := matches[valueArrayIndex]
|
||||
valuePackage := matches[valuePackageIndex]
|
||||
valueType := matches[valueTypeIndex]
|
||||
// fmt.Printf("input=%s, keyPackage=%s, keyType=%s, valueArray=%s, valuePackage=%s, valueType=%s\n",
|
||||
// input,
|
||||
// keyPackage,
|
||||
// keyType,
|
||||
// valueArray,
|
||||
// valuePackage,
|
||||
// valueType)
|
||||
// goTypeToJSDocType converts a Go type string to a JSDoc/TypeScript type string.
|
||||
func goTypeToJSDocType(goType string) string {
|
||||
goType = strings.TrimSpace(goType)
|
||||
|
||||
// byte array is special case
|
||||
if valueArray == "[]" && valueType == "byte" {
|
||||
// Handle pointers
|
||||
for strings.HasPrefix(goType, "*") {
|
||||
goType = strings.TrimPrefix(goType, "*")
|
||||
goType = strings.TrimSpace(goType)
|
||||
}
|
||||
|
||||
// Special-case []byte -> string
|
||||
if goType == "[]byte" {
|
||||
return "string"
|
||||
}
|
||||
|
||||
// if any packages, make sure they're saved
|
||||
if len(keyPackage) > 0 {
|
||||
importNamespaces.Add(keyPackage)
|
||||
// Handle arrays/slices in legacy "Array<>" style
|
||||
if strings.HasPrefix(goType, "[]") {
|
||||
elemType := strings.TrimPrefix(goType, "[]")
|
||||
elemJS := goTypeToJSDocType(elemType)
|
||||
return fmt.Sprintf("Array<%s>", elemJS)
|
||||
}
|
||||
|
||||
if len(valuePackage) > 0 {
|
||||
importNamespaces.Add(valuePackage)
|
||||
// Handle maps with bracket-depth logic
|
||||
if strings.HasPrefix(goType, "map[") {
|
||||
keyStart := len("map[")
|
||||
depth := 1
|
||||
keyEnd := -1
|
||||
for i, r := range goType[keyStart:] {
|
||||
switch r {
|
||||
case '[':
|
||||
depth++
|
||||
case ']':
|
||||
depth--
|
||||
if depth == 0 {
|
||||
keyEnd = keyStart + i
|
||||
break
|
||||
}
|
||||
}
|
||||
if keyEnd != -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if keyEnd == -1 || keyEnd+1 >= len(goType) {
|
||||
return "any"
|
||||
}
|
||||
keyType := goType[keyStart:keyEnd]
|
||||
valType := strings.TrimSpace(goType[keyEnd+1:])
|
||||
return fmt.Sprintf("Record<%s, %s>", goTypeToJSDocType(keyType), goTypeToJSDocType(valType))
|
||||
}
|
||||
|
||||
key := fullyQualifiedName(keyPackage, keyType)
|
||||
var value string
|
||||
if strings.HasPrefix(valueType, "map") {
|
||||
value = goTypeToJSDocType(valueType, importNamespaces)
|
||||
} else {
|
||||
value = fullyQualifiedName(valuePackage, valueType)
|
||||
// Generic type pattern (legacy underscore flattening)
|
||||
// Note: This pattern matches the innermost brackets for nested generics.
|
||||
// Nested generics like Outer[Inner[T]] are not currently supported.
|
||||
if matches := genericTypePattern.FindStringSubmatch(goType); len(matches) == 3 {
|
||||
base := matches[1]
|
||||
inner := jsVariableUnsafeChars.ReplaceAllLiteralString(matches[2], "_")
|
||||
inner = strings.TrimPrefix(inner, "_") // remove leading underscore if any
|
||||
return fmt.Sprintf("%s_%s_", base, inner)
|
||||
}
|
||||
|
||||
if len(key) > 0 {
|
||||
return fmt.Sprintf("Record<%s, %s>", key, arrayifyValue(valueArray, value))
|
||||
// If fully qualified and not in customTypeMap, use name unchanged
|
||||
if strings.Contains(goType, ".") {
|
||||
// Check if this is a custom type that should be mapped
|
||||
if tsType, ok := customTypeMap[goType]; ok {
|
||||
return tsType
|
||||
}
|
||||
|
||||
// Normal fully-qualified name (main.SomeType)
|
||||
if !strings.Contains(goType, "[") {
|
||||
return goType
|
||||
}
|
||||
}
|
||||
|
||||
return arrayifyValue(valueArray, value)
|
||||
// customTypeMap lookup for base name
|
||||
if mapped, ok := customTypeMap[goType]; ok {
|
||||
return mapped
|
||||
}
|
||||
|
||||
// Basic mappings
|
||||
switch goType {
|
||||
case "string":
|
||||
return "string"
|
||||
case "error":
|
||||
return "Error"
|
||||
case "bool":
|
||||
return "boolean"
|
||||
case "interface{}":
|
||||
return "any"
|
||||
case "int", "int8", "int16", "int32", "int64",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
"float32", "float64":
|
||||
return "number"
|
||||
}
|
||||
|
||||
return "any"
|
||||
}
|
||||
|
||||
func goTypeToTypescriptType(input string, importNamespaces *slicer.StringSlicer) string {
|
||||
return goTypeToJSDocType(input, importNamespaces)
|
||||
func goTypeToTypescriptType(input string, _ *slicer.StringSlicer) string {
|
||||
return goTypeToJSDocType(input)
|
||||
}
|
||||
|
||||
func entityFullReturnType(input, prefix, suffix string, importNamespaces *slicer.StringSlicer) string {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package binding
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/leaanthony/slicer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
)
|
||||
|
|
@ -138,11 +137,40 @@ func Test_goTypeToJSDocType(t *testing.T) {
|
|||
input: "main.ListData[*net/http.Request]",
|
||||
want: "main.ListData_net_http_Request_",
|
||||
},
|
||||
{
|
||||
name: "time.Time mapped to string",
|
||||
input: "time.Time",
|
||||
want: "string",
|
||||
},
|
||||
{
|
||||
name: "url.URL mapped to string",
|
||||
input: "url.URL",
|
||||
want: "string",
|
||||
},
|
||||
{
|
||||
name: "uuid.UUID mapped to string",
|
||||
input: "uuid.UUID",
|
||||
want: "string",
|
||||
},
|
||||
{
|
||||
name: "slice of time.Time",
|
||||
input: "[]time.Time",
|
||||
want: "Array<string>",
|
||||
},
|
||||
{
|
||||
name: "map of uuid.UUID",
|
||||
input: "map[string]uuid.UUID",
|
||||
want: "Record<string, string>",
|
||||
},
|
||||
{
|
||||
name: "pointer to time.Time",
|
||||
input: "*time.Time",
|
||||
want: "string",
|
||||
},
|
||||
}
|
||||
var importNamespaces slicer.StringSlicer
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := goTypeToJSDocType(tt.input, &importNamespaces); got != tt.want {
|
||||
if got := goTypeToJSDocType(tt.input); got != tt.want {
|
||||
t.Errorf("goTypeToJSDocType() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue