mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
[v3] MUCH Improved parser for bound structs
This commit is contained in:
+199
-285
File diff suppressed because it is too large
Load Diff
@@ -3,60 +3,215 @@ package parser
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestParseDirectory(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
want []string
|
||||
wantErr bool
|
||||
name string
|
||||
dir string
|
||||
wantBoundMethods map[string]map[string][]*BoundMethod
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "should find single bound service",
|
||||
dir: "testdata/struct_literal_single",
|
||||
want: []string{"main.GreetService"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should find multiple bound services",
|
||||
dir: "testdata/struct_literal_multiple",
|
||||
want: []string{"main.GreetService", "main.OtherService"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should find multiple bound services over multiple files",
|
||||
dir: "testdata/struct_literal_multiple_files",
|
||||
want: []string{"main.GreetService", "main.OtherService"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should find multiple bound services over multiple packages",
|
||||
dir: "testdata/struct_literal_multiple_other",
|
||||
want: []string{"main.GreetService", "services.OtherService"},
|
||||
name: "should find single bound service",
|
||||
dir: "testdata/struct_literal_single",
|
||||
//wantModels: []string{"main.GreetService"},
|
||||
wantBoundMethods: map[string]map[string][]*BoundMethod{
|
||||
"main": {
|
||||
"GreetService": {
|
||||
{
|
||||
Name: "Greet",
|
||||
DocComment: "Greet someone\n",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "name",
|
||||
Type: "string",
|
||||
IsStruct: false,
|
||||
IsSlice: false,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Name: "",
|
||||
Type: "string",
|
||||
IsStruct: false,
|
||||
IsSlice: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NoInputsStringOut",
|
||||
DocComment: "",
|
||||
Inputs: nil,
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Name: "",
|
||||
Type: "string",
|
||||
IsStruct: false,
|
||||
IsSlice: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StringArrayInputStringOut",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StringArrayInputStringArrayOut",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StringArrayInputNamedOutput",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Name: "output",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StringArrayInputNamedOutputs",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Name: "output",
|
||||
Type: "string",
|
||||
IsSlice: true,
|
||||
},
|
||||
{
|
||||
Name: "err",
|
||||
Type: "error",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "IntPointerInputNamedOutputs",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "int",
|
||||
IsPointer: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Name: "output",
|
||||
Type: "int",
|
||||
IsPointer: true,
|
||||
},
|
||||
{
|
||||
Name: "err",
|
||||
Type: "error",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StructPointerInputErrorOutput",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "Person",
|
||||
IsStruct: true,
|
||||
IsPointer: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Type: "error",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "StructPointerInputStructPointerOutput",
|
||||
Inputs: []*Parameter{
|
||||
{
|
||||
Name: "in",
|
||||
Type: "Person",
|
||||
IsStruct: true,
|
||||
IsPointer: true,
|
||||
},
|
||||
},
|
||||
Outputs: []*Parameter{
|
||||
{
|
||||
Type: "Person",
|
||||
IsPointer: true,
|
||||
IsStruct: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
//{
|
||||
// name: "should find multiple bound services",
|
||||
// dir: "testdata/struct_literal_multiple",
|
||||
// //wantModels: []string{"main.GreetService", "main.OtherService"},
|
||||
// wantErr: false,
|
||||
//},
|
||||
//{
|
||||
// name: "should find multiple bound services over multiple files",
|
||||
// dir: "testdata/struct_literal_multiple_files",
|
||||
// //wantModels: []string{"main.GreetService", "main.OtherService"},
|
||||
// wantErr: false,
|
||||
//},
|
||||
//{
|
||||
// name: "should find multiple bound services over multiple packages",
|
||||
// dir: "testdata/struct_literal_multiple_other",
|
||||
// //wantModels: []string{"main.GreetService", "services.OtherService", "main.Person"},
|
||||
// wantErr: false,
|
||||
//},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
Debug = true
|
||||
got, err := ParseDirectory(tt.dir)
|
||||
got, err := ParseProject(tt.dir)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ParseDirectory() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
for name, pkg := range got.packages {
|
||||
for structName, structType := range pkg.boundStructs {
|
||||
require.NotNil(t, structType)
|
||||
require.True(t, lo.Contains(tt.want, name+"."+structName))
|
||||
tt.want = lo.Without(tt.want, name+"."+structName)
|
||||
}
|
||||
if diff := cmp.Diff(tt.wantBoundMethods, got.BoundMethods); diff != "" {
|
||||
t.Errorf("ParseDirectory() failed:\n" + diff)
|
||||
}
|
||||
require.Empty(t, tt.want)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,13 +221,13 @@ func TestParseDirectory(t *testing.T) {
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// dir string
|
||||
// want string
|
||||
// wantModels string
|
||||
// wantErr bool
|
||||
// }{
|
||||
// {
|
||||
// name: "should find single bound service",
|
||||
// dir: "testdata/struct_literal_single",
|
||||
// want: `namespace main {
|
||||
// wantModels: `namespace main {
|
||||
// class GreetService {
|
||||
// SomeVariable: number;
|
||||
// }
|
||||
@@ -83,7 +238,7 @@ func TestParseDirectory(t *testing.T) {
|
||||
// {
|
||||
// name: "should find multiple bound services",
|
||||
// dir: "testdata/struct_literal_multiple",
|
||||
// want: `namespace main {
|
||||
// wantModels: `namespace main {
|
||||
// class GreetService {
|
||||
// SomeVariable: number;
|
||||
// }
|
||||
@@ -96,7 +251,7 @@ func TestParseDirectory(t *testing.T) {
|
||||
// {
|
||||
// name: "should find multiple bound services over multiple files",
|
||||
// dir: "testdata/struct_literal_multiple_files",
|
||||
// want: `namespace main {
|
||||
// wantModels: `namespace main {
|
||||
// class GreetService {
|
||||
// SomeVariable: number;
|
||||
// }
|
||||
@@ -109,7 +264,7 @@ func TestParseDirectory(t *testing.T) {
|
||||
// {
|
||||
// name: "should find bound services from other packages",
|
||||
// dir: "../../examples/binding",
|
||||
// want: `namespace main {
|
||||
// wantModels: `namespace main {
|
||||
// class localStruct {
|
||||
// }
|
||||
//}
|
||||
@@ -139,7 +294,7 @@ func TestParseDirectory(t *testing.T) {
|
||||
//
|
||||
// ts, err := GenerateModels(context)
|
||||
// require.NoError(t, err)
|
||||
// require.Equal(t, tt.want, string(ts))
|
||||
// require.Equal(t, tt.wantModels, string(ts))
|
||||
//
|
||||
// })
|
||||
// }
|
||||
|
||||
@@ -12,6 +12,11 @@ import (
|
||||
type GreetService struct {
|
||||
SomeVariable int
|
||||
lowerCase string
|
||||
target *Person
|
||||
}
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// Greet does XYZ
|
||||
@@ -19,6 +24,11 @@ func (*GreetService) Greet(name string) string {
|
||||
return "Hello " + name
|
||||
}
|
||||
|
||||
// NewPerson creates a new person
|
||||
func (*GreetService) NewPerson(name string) *Person {
|
||||
return &Person{Name: name}
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := application.New(application.Options{
|
||||
Bind: []interface{}{
|
||||
|
||||
+2
-2
@@ -7,6 +7,6 @@ type OtherService struct {
|
||||
}
|
||||
|
||||
// Yay does this and that
|
||||
func (o *OtherService) Yay() {
|
||||
|
||||
func (o *OtherService) Yay() []int {
|
||||
return []int{0, 1, 2}
|
||||
}
|
||||
|
||||
@@ -3,19 +3,58 @@ package main
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// GreetService is great
|
||||
type GreetService struct {
|
||||
SomeVariable int
|
||||
lowerCase string
|
||||
}
|
||||
|
||||
// Greet someone
|
||||
func (*GreetService) Greet(name string) string {
|
||||
return "Hello " + name
|
||||
}
|
||||
|
||||
func (*GreetService) NoInputsStringOut() string {
|
||||
return "Hello"
|
||||
}
|
||||
|
||||
func (*GreetService) StringArrayInputStringOut(in []string) string {
|
||||
return strings.Join(in, ",")
|
||||
}
|
||||
|
||||
func (*GreetService) StringArrayInputStringArrayOut(in []string) []string {
|
||||
return in
|
||||
}
|
||||
|
||||
func (*GreetService) StringArrayInputNamedOutput(in []string) (output []string) {
|
||||
return in
|
||||
}
|
||||
|
||||
func (*GreetService) StringArrayInputNamedOutputs(in []string) (output []string, err error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (*GreetService) IntPointerInputNamedOutputs(in *int) (output *int, err error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (*GreetService) StructPointerInputErrorOutput(in *Person) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*GreetService) StructPointerInputStructPointerOutput(in *Person) *Person {
|
||||
return in
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := application.New(application.Options{
|
||||
Bind: []interface{}{
|
||||
|
||||
Reference in New Issue
Block a user