diff --git a/pkg/gen/filters/common/helper_test.go b/pkg/gen/filters/common/helper_test.go index c8d447b5..b9658a01 100644 --- a/pkg/gen/filters/common/helper_test.go +++ b/pkg/gen/filters/common/helper_test.go @@ -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) { @@ -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" , "", "", "ab::c", "abc", "ghi", "" } - var noDuplicatesList = []string{"" , "", "ab::c", "abc", "ghi"} + var inputList = []string{"abc", "", "", "ab::c", "abc", "ghi", ""} + var noDuplicatesList = []string{"", "", "ab::c", "abc", "ghi"} t.Run("getListOfFields", func(t *testing.T) { - assert.Equal(t, noDuplicatesList, Unique(inputList)) - }) -} \ No newline at end of file + assert.Equal(t, noDuplicatesList, Unique(inputList)) + }) +} diff --git a/pkg/gen/filters/filterue/filters.go b/pkg/gen/filters/filterue/filters.go index e4416fa8..f7e28d8c 100644 --- a/pkg/gen/filters/filterue/filters.go +++ b/pkg/gen/filters/filterue/filters.go @@ -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 diff --git a/pkg/gen/filters/filterue/ue_default_test.go b/pkg/gen/filters/filterue/ue_default_test.go index d6050803..e2116ccf 100644 --- a/pkg/gen/filters/filterue/ue_default_test.go +++ b/pkg/gen/filters/filterue/ue_default_test.go @@ -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()"}, diff --git a/pkg/gen/filters/filterue/ue_extern.go b/pkg/gen/filters/filterue/ue_extern.go index 8b5a01c4..cdd8bb10 100644 --- a/pkg/gen/filters/filterue/ue_extern.go +++ b/pkg/gen/filters/filterue/ue_extern.go @@ -9,6 +9,7 @@ type UeExtern struct { Include string Name string Library string + Plugin string } func parseUeExtern(schema *model.Schema) UeExtern { @@ -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 } @@ -29,5 +31,6 @@ func ueExtern(xe *model.Extern) UeExtern { Include: inc, Name: name, Library: lib, + Plugin: plugin, } } diff --git a/pkg/gen/filters/filterue/ue_testvalue.go b/pkg/gen/filters/filterue/ue_testvalue.go new file mode 100644 index 00000000..fb16bb99 --- /dev/null +++ b/pkg/gen/filters/filterue/ue_testvalue.go @@ -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) +} diff --git a/pkg/gen/filters/filterue/ue_testvalue_test.go b/pkg/gen/filters/filterue/ue_testvalue_test.go new file mode 100644 index 00000000..c4fec958 --- /dev/null +++ b/pkg/gen/filters/filterue/ue_testvalue_test.go @@ -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()"}, + {"test", "Test1", "propIntArray", "TArray()"}, + {"test", "Test1", "propInt32Array", "TArray()"}, + {"test", "Test1", "propInt64Array", "TArray()"}, + {"test", "Test1", "propFloatArray", "TArray()"}, + {"test", "Test1", "propFloat32Array", "TArray()"}, + {"test", "Test1", "propFloat64Array", "TArray()"}, + {"test", "Test1", "propStringArray", "TArray()"}, + } + 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()"}, + {"test", "Test2", "propStructArray", "TArray()"}, + {"test", "Test2", "propInterfaceArray", "TArray()"}, + } + 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) +} diff --git a/pkg/gen/filters/testdata/test.idl b/pkg/gen/filters/testdata/test.idl index bb891d34..2dcb38be 100644 --- a/pkg/gen/filters/testdata/test.idl +++ b/pkg/gen/filters/testdata/test.idl @@ -105,11 +105,13 @@ interface InterfaceNamesCheck { enum Enum1 { Default = 0, + NotDefault = 1, } enum EnumLowerNames { firstValue = 0, + secondValue = 1, } struct Struct1 {} \ No newline at end of file diff --git a/pkg/helper/strings.go b/pkg/helper/strings.go index 993afa1f..1af8a4ca 100644 --- a/pkg/helper/strings.go +++ b/pkg/helper/strings.go @@ -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