-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(python): add filter for test value
adds a filter which, for simple types sets some value that is different than the default value. For enum it returns te second value (if present). For the arrays it returns an element of that type For structs it returns the default value. This is used by a python template for #35 ticket
- Loading branch information
1 parent
8dbaa0b
commit 4f39064
Showing
4 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package filterpy | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/apigear-io/cli/pkg/gen/filters/common" | ||
"github.com/apigear-io/cli/pkg/model" | ||
) | ||
|
||
// ToTestValueString returns the test value string for a given schema. | ||
// We intentionally ignore arrays in order to return the test value of the inner type. | ||
func ToTestValueString(prefix string, schema *model.Schema) (string, error) { | ||
if schema == nil { | ||
return "xxx", fmt.Errorf("pyTestValue schema is nil") | ||
} | ||
if schema.Module == nil { | ||
return "xxx", fmt.Errorf("pyTestValue schema module is nil") | ||
} | ||
var text string | ||
switch schema.KindType { | ||
case model.TypeString: | ||
text = "\"xyz\"" | ||
case model.TypeInt, model.TypeInt32, model.TypeInt64: | ||
text = "1" | ||
case model.TypeFloat, model.TypeFloat32, model.TypeFloat64: | ||
text = "1.1" | ||
case model.TypeBool: | ||
text = "True" | ||
case model.TypeVoid: | ||
return ToDefaultString(schema, prefix) | ||
case model.TypeEnum: | ||
e_local := schema.LookupEnum("", schema.Type) | ||
e_imported := schema.LookupEnum(schema.Import, schema.Type) | ||
if e_local == nil && e_imported == nil { | ||
return "xxx", fmt.Errorf("pyTestValue enum not found: %s", schema.Dump()) | ||
} | ||
// if enum is local it is found both as e_local and e_imported | ||
name := common.CamelTitleCase(e_imported.Name) | ||
member := common.SnakeUpperCase(e_imported.Members[0].Name) | ||
if len(e_imported.Members) > 1 { | ||
member = common.SnakeUpperCase(e_imported.Members[1].Name) | ||
} | ||
if e_local == nil { | ||
prefix = fmt.Sprintf("%s.api.", e_imported.Module.Name) | ||
} | ||
text = fmt.Sprintf("%s%s.%s", prefix, name, member) | ||
case model.TypeStruct: | ||
s_local := schema.LookupStruct("", schema.Type) | ||
s_imported := schema.LookupStruct(schema.Import, schema.Type) | ||
if s_local == nil && s_imported == nil { | ||
return "xxx", fmt.Errorf("pyTestValue struct not found: %s", schema.Dump()) | ||
} | ||
// if struct is local it is found both as s_local and s_imported | ||
ident := common.CamelTitleCase(s_imported.Name) | ||
if s_local == nil { | ||
prefix = fmt.Sprintf("%s.api.", s_imported.Module.Name) | ||
} | ||
text = fmt.Sprintf("%s%s()", prefix, ident) | ||
case model.TypeExtern: | ||
xe := parsePyExtern(schema) | ||
if xe.Default != "" { | ||
text = xe.Default | ||
} else { | ||
py_module := "" | ||
if xe.Import != "" { | ||
py_module = fmt.Sprintf("%s.", xe.Import) | ||
} | ||
text = fmt.Sprintf("%s%s()", py_module, xe.Name) | ||
} | ||
case model.TypeInterface: | ||
i_local := schema.LookupInterface("", schema.Type) | ||
i_imported := schema.LookupInterface(schema.Import, schema.Type) | ||
if i_local == nil && i_imported == nil { | ||
return "xxx", fmt.Errorf("pyTestValue interface not found: %s", schema.Dump()) | ||
} | ||
// if interface is local it is found both as s_local and s_imported | ||
ident := common.CamelTitleCase(i_imported.Name) | ||
if i_local == nil { | ||
prefix = fmt.Sprintf("%s.api.", i_imported.Module.Name) | ||
} | ||
text = fmt.Sprintf("%s%s()", prefix, ident) | ||
default: | ||
return "xxx", fmt.Errorf("pyTestValue unknown schema %s", schema.Dump()) | ||
} | ||
return text, nil | ||
} | ||
|
||
func pyTestValue(prefix string, node *model.TypedNode) (string, error) { | ||
if node == nil { | ||
return "xxx", fmt.Errorf("pyTestValue node is nil") | ||
} | ||
return ToTestValueString(prefix, &node.Schema) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package filterpy | ||
|
||
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", "propVoid", "None"}, | ||
{"test", "Test1", "propBool", "True"}, | ||
{"test", "Test1", "propInt", "1"}, | ||
{"test", "Test1", "propInt32", "1"}, | ||
{"test", "Test1", "propInt64", "1"}, | ||
{"test", "Test1", "propFloat", "1.1"}, | ||
{"test", "Test1", "propFloat32", "1.1"}, | ||
{"test", "Test1", "propFloat64", "1.1"}, | ||
{"test", "Test1", "propString", "\"xyz\""}, | ||
{"test", "Test1", "propBoolArray", "True"}, // all the array types return value intentionally, it may be put into empty array | ||
{"test", "Test1", "propIntArray", "1"}, | ||
{"test", "Test1", "propInt32Array", "1"}, | ||
{"test", "Test1", "propInt64Array", "1"}, | ||
{"test", "Test1", "propFloatArray", "1.1"}, | ||
{"test", "Test1", "propFloat32Array", "1.1"}, | ||
{"test", "Test1", "propFloat64Array", "1.1"}, | ||
{"test", "Test1", "propStringArray", "\"xyz\""}, | ||
} | ||
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 := pyTestValue("", 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 | ||
rt string | ||
}{ | ||
{"test", "Test2", "propEnum", "Enum1.NOT_DEFAULT"}, | ||
{"test", "Test2", "propStruct", "Struct1()"}, | ||
{"test", "Test2", "propInterface", "Interface1()"}, | ||
{"test", "Test2", "propEnumArray", "Enum1.NOT_DEFAULT"}, | ||
{"test", "Test2", "propStructArray", "Struct1()"}, | ||
{"test", "Test2", "propInterfaceArray", "Interface1()"}, | ||
} | ||
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 := pyTestValue("", prop) | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.rt, r) | ||
}) | ||
} | ||
} | ||
} | ||
|
||
func TestTestValueWithErrors(t *testing.T) { | ||
t.Parallel() | ||
s, err := pyTestValue("", nil) | ||
assert.Error(t, err) | ||
assert.Equal(t, "xxx", s) | ||
} | ||
|
||
func TestTestValueReturnsExternDefault(t *testing.T) { | ||
syss := loadExternSystems(t) | ||
var propTests = []struct { | ||
mn string | ||
in string | ||
pn string | ||
rt string | ||
}{ | ||
{"demo", "Iface1", "prop1", "XType1()"}, | ||
{"demo", "Iface1", "prop2", "XType2()"}, | ||
{"demo", "Iface1", "prop3", "XType3A()"}, | ||
} | ||
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 := pyTestValue("", prop) | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.rt, r) | ||
}) | ||
} | ||
} | ||
} | ||
|
||
func TestTestValueReturnsDefaultExterns(t *testing.T) { | ||
t.Parallel() | ||
table := []struct { | ||
module_name string | ||
interface_name string | ||
operation_name string | ||
result string | ||
}{ | ||
{"test_apigear_next", "Iface1", "prop1", "XType1()"}, | ||
{"test_apigear_next", "Iface1", "prop2", "demo.x.XType2()"}, | ||
{"test_apigear_next", "Iface1", "prop3", "demo.x.createXType3A()"}, | ||
{"test_apigear_next", "Iface1", "propList", "demo.x.createXType3A()"}, | ||
{"test_apigear_next", "Iface1", "propImportedEnum", "test.api.Enum1.NOT_DEFAULT"}, | ||
{"test_apigear_next", "Iface1", "propImportedStruct", "test.api.Struct1()"}, | ||
} | ||
syss := loadExternSystemsYAML(t) | ||
prefix := "my_prefix::" | ||
for _, sys := range syss { | ||
for _, tt := range table { | ||
t.Run(tt.operation_name, func(t *testing.T) { | ||
prop := sys.LookupProperty(tt.module_name, tt.interface_name, tt.operation_name) | ||
assert.NotNil(t, prop) | ||
r, err := pyTestValue(prefix, prop) | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.result, r) | ||
}) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters