diff --git a/v3/internal/parser/models_test.go b/v3/internal/parser/models_test.go index b533f703..2020968c 100644 --- a/v3/internal/parser/models_test.go +++ b/v3/internal/parser/models_test.go @@ -12,8 +12,9 @@ import ( func TestGenerateModels(t *testing.T) { tests := []struct { - dir string - want string + dir string + want string + useInterface bool }{ { dir: "testdata/function_single", @@ -50,6 +51,11 @@ func TestGenerateModels(t *testing.T) { dir: "testdata/enum", want: getFile("testdata/enum/models.ts"), }, + { + dir: "testdata/enum-interface", + want: getFile("testdata/enum-interface/models.ts"), + useInterface: true, + }, } for _, tt := range tests { t.Run(tt.dir, func(t *testing.T) { @@ -60,7 +66,9 @@ func TestGenerateModels(t *testing.T) { } // Generate Models - got, err := GenerateModels(project.Models, project.Types, &flags.GenerateBindingsOptions{}) + got, err := GenerateModels(project.Models, project.Types, &flags.GenerateBindingsOptions{ + UseInterfaces: tt.useInterface, + }) if err != nil { t.Fatalf("GenerateModels() error = %v", err) } diff --git a/v3/internal/parser/parser_enum_test.go b/v3/internal/parser/parser_enum_test.go index 3d3926ac..c08bf157 100644 --- a/v3/internal/parser/parser_enum_test.go +++ b/v3/internal/parser/parser_enum_test.go @@ -18,7 +18,7 @@ func TestParseEnum(t *testing.T) { wantErr bool }{ { - name: "should find a bound services with an enum", + name: "should find a bound service with an enum", dir: "testdata/enum", wantErr: false, wantBoundMethods: map[string]map[string][]*BoundMethod{ @@ -139,6 +139,128 @@ func TestParseEnum(t *testing.T) { }, }, }, + { + name: "should find a bound service with an enum interface", + dir: "testdata/enum-interface", + wantErr: false, + wantBoundMethods: map[string]map[string][]*BoundMethod{ + "main": { + "GreetService": { + { + Name: "Greet", + DocComment: "Greet does XYZ", + Inputs: []*Parameter{ + { + Name: "name", + Type: &ParameterType{ + Package: "main", + Name: "string", + }, + }, + { + Name: "title", + Type: &ParameterType{ + Package: "main", + Name: "Title", + IsEnum: true, + }, + }, + }, + Outputs: []*Parameter{ + { + Name: "", + Type: &ParameterType{ + Package: "main", + Name: "string", + }, + }, + }, + ID: 1411160069, + }, + { + Name: "NewPerson", + DocComment: "NewPerson creates a new person", + Inputs: []*Parameter{ + { + Name: "name", + Type: &ParameterType{ + Package: "main", + Name: "string", + }, + }, + }, + Outputs: []*Parameter{ + { + Type: &ParameterType{ + Package: "main", + Name: "Person", + IsStruct: true, + IsPointer: true, + }, + }, + }, + ID: 1661412647, + }, + }, + }, + }, + wantTypes: map[string]map[string]*TypeDef{ + "main": { + "Title": { + Name: "Title", + Type: "string", + Consts: []*ConstDef{ + { + Name: "Mister", + DocComment: "Mister is a title", + Value: `"Mr"`, + }, + { + Name: "Miss", + Value: `"Miss"`, + }, + { + Name: "Ms", + Value: `"Ms"`, + }, + { + Name: "Mrs", + Value: `"Mrs"`, + }, + { + Name: "Dr", + Value: `"Dr"`, + }, + }, + ShouldGenerate: true, + }, + }, + }, + wantModels: map[string]map[string]*StructDef{ + "main": { + "Person": { + Name: "Person", + Fields: []*Field{ + { + Name: "Title", + Type: &ParameterType{ + Package: "main", + Name: "Title", + IsEnum: true, + }, + }, + { + Name: "Name", + Type: &ParameterType{ + Package: "main", + Name: "string", + }, + }, + }, + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/v3/internal/parser/templates/interfaces.ts.tmpl b/v3/internal/parser/templates/interfaces.ts.tmpl index a65a8a0f..18d52932 100644 --- a/v3/internal/parser/templates/interfaces.ts.tmpl +++ b/v3/internal/parser/templates/interfaces.ts.tmpl @@ -1,5 +1,17 @@ {{$pkg := .Package}} export namespace {{.Package}} { + {{range $enumindex, $enumdef := .Enums}} + {{- range $commentindex, $commentdef := .DocComments}} + {{$commentdef -}} + {{- end}} + export enum {{$enumdef.Name}} { + {{- range $constindex, $constdef := .Consts}} + {{- if $constdef.DocComment}} + // {{$constdef.DocComment}} + {{- end}} + {{$constdef.Name}} = {{$constdef.Value}},{{end}} + } + {{- end}} {{range $name, $def := .Models}} export interface {{$def.Name}} { {{range $def.Fields}} {{.JSDef $pkg}}{{end}} diff --git a/v3/internal/parser/testdata/enum-interface/bindings_main.js b/v3/internal/parser/testdata/enum-interface/bindings_main.js new file mode 100644 index 00000000..e00a3076 --- /dev/null +++ b/v3/internal/parser/testdata/enum-interface/bindings_main.js @@ -0,0 +1,29 @@ +// @ts-check +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +/** + * @typedef {import('./models').main.Title} mainTitle + * @typedef {import('./models').main.Person} mainPerson + */ + +export const GreetService = { + + /** + * GreetService.Greet + * Greet does XYZ + * @param name {string} + * @param title {mainTitle} + * @returns {Promise} + **/ + Greet: function(name, title) { return wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); }, + + /** + * GreetService.NewPerson + * NewPerson creates a new person + * @param name {string} + * @returns {Promise} + **/ + NewPerson: function(name) { return wails.CallByID(1661412647, ...Array.prototype.slice.call(arguments, 0)); }, +}; + diff --git a/v3/internal/parser/testdata/enum-interface/main.go b/v3/internal/parser/testdata/enum-interface/main.go new file mode 100644 index 00000000..e4677ec7 --- /dev/null +++ b/v3/internal/parser/testdata/enum-interface/main.go @@ -0,0 +1,58 @@ +package main + +import ( + _ "embed" + "log" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +type Title string + +const ( + // Mister is a title + Mister Title = "Mr" + Miss Title = "Miss" + Ms Title = "Ms" + Mrs Title = "Mrs" + Dr Title = "Dr" +) + +// GreetService is great +type GreetService struct { + SomeVariable int + lowerCase string + target *Person +} + +type Person struct { + Title Title + Name string +} + +// Greet does XYZ +func (*GreetService) Greet(name string, title Title) string { + return "Hello " + string(title) + " " + 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{}{ + &GreetService{}, + }, + }) + + app.NewWebviewWindow() + + err := app.Run() + + if err != nil { + log.Fatal(err) + } + +} diff --git a/v3/internal/parser/testdata/enum-interface/models.ts b/v3/internal/parser/testdata/enum-interface/models.ts new file mode 100644 index 00000000..46845592 --- /dev/null +++ b/v3/internal/parser/testdata/enum-interface/models.ts @@ -0,0 +1,21 @@ +// @ts-check +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +export namespace main { + + export enum Title { + // Mister is a title + Mister = "Mr", + Miss = "Miss", + Ms = "Ms", + Mrs = "Mrs", + Dr = "Dr", + } + + export interface Person { + title: Title; + name: string; + } + +}