Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc changes for UE template #151

Merged
merged 4 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 27 additions & 25 deletions pkg/gen/filters/common/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,18 @@ func TestAbbreviate(t *testing.T) {
{"hEllo.worLd", "HEWL"},
{"HEllo.worLd", "HEWL"},
{"HEllo.worLD", "HEWL"},
{"HEllo.worLD2", "HEWL2"},
{"HELlo.worLD", "HLWL"},
{"hello_world", "HW"},
{"heLlo_wOrld", "HLWO"},
{"hello world", "HW"},
{"hello worlD", "HWD"},
{"hello.2world", "H"},
{"hello.2world", "H2"},
{"1hello.world", "W"},
{"1hello.2world", ""},
{"1hELlo.2world", "EL"},
{"1hELLlo.2world", "EL"},
{"1hELlo.2world", "EL2"},
{"1hELLlo.2world", "EL2"},
{"1hELLlo.2woRld", "EL2R"},
}
for _, tt := range tests {
t.Run(tt.out, func(t *testing.T) {
Expand All @@ -143,48 +145,48 @@ func TestAbbreviate(t *testing.T) {
func TestCollectFields(t *testing.T) {
t.Parallel()
var listOfStructs = []struct {
a string
b string
a string
b string
}{
{"foo1", "goo1"},
{"foo2", "goo2"},
{"foo3", "goo3"},
}
var listA = []string{"foo1" , "foo2", "foo3"}
var listB = []string{"goo1" , "goo2", "goo3"}
var listA = []string{"foo1", "foo2", "foo3"}
var listB = []string{"goo1", "goo2", "goo3"}
t.Run("getListOfFields", func(t *testing.T) {
resultA, err := CollectFields(listOfStructs, "a")
assert.Equal(t, listA, resultA)
assert.NoError(t, err)
resultB, err := CollectFields(listOfStructs, "b")
assert.Equal(t, listB, resultB)
assert.NoError(t, err)
})
resultA, err := CollectFields(listOfStructs, "a")
assert.Equal(t, listA, resultA)
assert.NoError(t, err)
resultB, err := CollectFields(listOfStructs, "b")
assert.Equal(t, listB, resultB)
assert.NoError(t, err)
})
}

func TestNoFieldCollectFields(t *testing.T) {
t.Parallel()
var listOfStructs = []struct {
a string
b string
a string
b string
}{
{"foo1", "goo1"},
}
var emptyList = []string{}
t.Run("getListOfFields", func(t *testing.T) {
result, err := CollectFields(listOfStructs, "c")
assert.Equal(t, emptyList, result)
assert.Error(t, err)
})
result, err := CollectFields(listOfStructs, "c")
assert.Equal(t, emptyList, result)
assert.Error(t, err)
})
}

func TestUnique(t *testing.T) {
t.Parallel()

var inputList = []string{"abc" , "<def>", "<ghi>", "ab::c", "abc", "ghi", "<ghi>" }
var noDuplicatesList = []string{"<def>" , "<ghi>", "ab::c", "abc", "ghi"}
var inputList = []string{"abc", "<def>", "<ghi>", "ab::c", "abc", "ghi", "<ghi>"}
var noDuplicatesList = []string{"<def>", "<ghi>", "ab::c", "abc", "ghi"}

t.Run("getListOfFields", func(t *testing.T) {
assert.Equal(t, noDuplicatesList, Unique(inputList))
})
}
assert.Equal(t, noDuplicatesList, Unique(inputList))
})
}
1 change: 1 addition & 0 deletions pkg/gen/filters/filterue/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ func PopulateFuncMap(fm template.FuncMap) {
fm["ueParams"] = ueParams
fm["ueReturn"] = ueReturn
fm["ueDefault"] = ueDefault
fm["ueTestValue"] = ueTestValue
fm["ueConstType"] = ueConstType
fm["ueType"] = ueType
fm["ueVar"] = ueVar
Expand Down
2 changes: 1 addition & 1 deletion pkg/gen/filters/filterue/ue_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestDefaultSymbolsFromIdl(t *testing.T) {
val string
}{
// EnumValues: {"test", "Test2", "propEnum", "ETestEnum1::Default"},
{"test", "Test2", "propEnum", "ETestEnum1::TE_DEFAULT"},
{"test", "Test2", "propEnum", "ETestEnum1::TE1_DEFAULT"},
{"test", "Test2", "propStruct", "FTestStruct1()"},
{"test", "Test2", "propInterface", "FTestInterface1()"},
{"test", "Test2", "propEnumArray", "TArray<ETestEnum1>()"},
Expand Down
3 changes: 3 additions & 0 deletions pkg/gen/filters/filterue/ue_extern.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type UeExtern struct {
Include string
Name string
Library string
Plugin string
}

func parseUeExtern(schema *model.Schema) UeExtern {
Expand All @@ -21,6 +22,7 @@ func ueExtern(xe *model.Extern) UeExtern {
inc := xe.Meta.GetString("ue.include")
lib := xe.Meta.GetString("ue.module")
name := xe.Meta.GetString("ue.type")
plugin := xe.Meta.GetString("ue.plugin")
if name == "" {
name = xe.Name
}
Expand All @@ -29,5 +31,6 @@ func ueExtern(xe *model.Extern) UeExtern {
Include: inc,
Name: name,
Library: lib,
Plugin: plugin,
}
}
67 changes: 67 additions & 0 deletions pkg/gen/filters/filterue/ue_testvalue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package filterue

import (
"fmt"

"github.com/apigear-io/cli/pkg/helper"
"github.com/apigear-io/cli/pkg/model"
"github.com/ettle/strcase"
)

func ToTestValueString(prefix string, schema *model.Schema) (string, error) {
if schema == nil {
return "", fmt.Errorf("ToDefaultString schema is nil")
}
moduleId := strcase.ToPascal(schema.Module.Name)
if schema.Import != "" {
moduleId = strcase.ToPascal(schema.Import)
}
var text string
if schema.IsArray {
return ToDefaultString(prefix, schema)
} else {
switch schema.KindType {
case model.TypeString:
text = "FString(\"xyz\")"
case model.TypeInt, model.TypeInt32:
text = "1"
case model.TypeInt64:
text = "1LL"
case model.TypeFloat, model.TypeFloat32:
text = "1.0f"
case model.TypeFloat64:
text = "1.0"
case model.TypeBool:
text = "true"
case model.TypeVoid:
return ToDefaultString(prefix, schema)
case model.TypeEnum:
symbol := schema.GetEnum()
member := symbol.Members[0]
if len(symbol.Members) > 1 {
member = symbol.Members[1]
}
typename := fmt.Sprintf("%s%s", moduleId, symbol.Name)
abbreviation := helper.Abbreviate(typename)
// upper case first letter
// TODO: EnumValues: using camel-cases for enum values: strcase.ToCamel(member.Name)
text = fmt.Sprintf("%sE%s::%s_%s", prefix, typename, abbreviation, strcase.ToCase(member.Name, strcase.UpperCase, '\x00'))
case model.TypeStruct:
return ToDefaultString(prefix, schema)
case model.TypeExtern:
return ToDefaultString(prefix, schema)
case model.TypeInterface:
return ToDefaultString(prefix, schema)
default:
return "xxx", fmt.Errorf("ueDefault unknown schema %s", schema.Dump())
}
}
return text, nil
}

func ueTestValue(prefix string, node *model.TypedNode) (string, error) {
if node == nil {
return "xxx", fmt.Errorf("ueDefault node is nil")
}
return ToTestValueString(prefix, &node.Schema)
}
85 changes: 85 additions & 0 deletions pkg/gen/filters/filterue/ue_testvalue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package filterue

import (
"testing"

"github.com/stretchr/testify/assert"
)

// test with all the types
// properties, operation params, operation return, signal params, struct fields
func TestTestValueFromIdl(t *testing.T) {
t.Parallel()
syss := loadTestSystems(t)
var propTests = []struct {
mn string
in string
pn string
rt string
}{
{"test", "Test1", "propBool", "true"},
{"test", "Test1", "propInt", "1"},
{"test", "Test1", "propInt32", "1"},
{"test", "Test1", "propInt64", "1LL"},
{"test", "Test1", "propFloat", "1.0f"},
{"test", "Test1", "propFloat32", "1.0f"},
{"test", "Test1", "propFloat64", "1.0"},
{"test", "Test1", "propString", "FString(\"xyz\")"},
{"test", "Test1", "propBoolArray", "TArray<bool>()"},
{"test", "Test1", "propIntArray", "TArray<int32>()"},
{"test", "Test1", "propInt32Array", "TArray<int32>()"},
{"test", "Test1", "propInt64Array", "TArray<int64>()"},
{"test", "Test1", "propFloatArray", "TArray<float>()"},
{"test", "Test1", "propFloat32Array", "TArray<float>()"},
{"test", "Test1", "propFloat64Array", "TArray<double>()"},
{"test", "Test1", "propStringArray", "TArray<FString>()"},
}
for _, sys := range syss {
for _, tt := range propTests {
t.Run(tt.pn, func(t *testing.T) {
prop := sys.LookupProperty(tt.mn, tt.in, tt.pn)
assert.NotNil(t, prop)
r, err := ueTestValue("", prop)
assert.NoError(t, err)
assert.Equal(t, tt.rt, r)
})
}
}
}

func TestTestValueSymbolsFromIdl(t *testing.T) {
t.Parallel()
syss := loadTestSystems(t)
var propTests = []struct {
mn string
in string
pn string
val string
}{
// EnumValues: {"test", "Test2", "propEnum", "ETestEnum1::Default"},
{"test", "Test2", "propEnum", "ETestEnum1::TE1_NOTDEFAULT"},
{"test", "Test2", "propStruct", "FTestStruct1()"},
{"test", "Test2", "propInterface", "FTestInterface1()"},
{"test", "Test2", "propEnumArray", "TArray<ETestEnum1>()"},
{"test", "Test2", "propStructArray", "TArray<FTestStruct1>()"},
{"test", "Test2", "propInterfaceArray", "TArray<FTestInterface1>()"},
}
for _, sys := range syss {
for _, tt := range propTests {
t.Run(tt.pn, func(t *testing.T) {
prop := sys.LookupProperty(tt.mn, tt.in, tt.pn)
assert.NotNil(t, prop)
r, err := ueTestValue("", prop)
assert.NoError(t, err)
assert.Equal(t, tt.val, r)
})
}
}
}

func TestTestValueWithErrors(t *testing.T) {
t.Parallel()
s, err := ueTestValue("", nil)
assert.Error(t, err)
assert.Equal(t, "xxx", s)
}
2 changes: 2 additions & 0 deletions pkg/gen/filters/testdata/test.idl
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ interface InterfaceNamesCheck {

enum Enum1 {
Default = 0,
NotDefault = 1,
}

enum EnumLowerNames
{
firstValue = 0,
secondValue = 1,
}

struct Struct1 {}
6 changes: 5 additions & 1 deletion pkg/helper/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ func ArrayToMap[T any](m map[string]T, e []T, f func(T) string) map[string]T {
return m
}

// Used by templates to generate abbreviation inside the code
// Used by templates to generate abbreviation including numbers inside the code
func Abbreviate(s string) string {
abbreviation := ""
for _, rune := range strcase.ToCase(s, strcase.TitleCase, '-') {
if unicode.IsUpper(rune) {
abbreviation += string(rune)
} else if unicode.IsNumber(rune) {
if len(abbreviation) > 0 {
abbreviation += string(rune)
}
}
}
return abbreviation
Expand Down
Loading