mirror of
https://github.com/php/frankenphp.git
synced 2026-03-24 09:02:11 +01:00
914 lines
21 KiB
Go
914 lines
21 KiB
Go
package extgen
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestValidateFunction(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
function phpFunction
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid function",
|
|
function: phpFunction{
|
|
Name: "validFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "param1", PhpType: phpString},
|
|
{Name: "param2", PhpType: phpInt},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with nullable return",
|
|
function: phpFunction{
|
|
Name: "nullableReturn",
|
|
ReturnType: phpString,
|
|
IsReturnNullable: true,
|
|
Params: []phpParameter{
|
|
{Name: "data", PhpType: phpArray},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with array parameter",
|
|
function: phpFunction{
|
|
Name: "arrayFunction",
|
|
ReturnType: phpArray,
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray},
|
|
{Name: "filter", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with nullable array parameter",
|
|
function: phpFunction{
|
|
Name: "nullableArrayFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray, IsNullable: true},
|
|
{Name: "name", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with array parameter",
|
|
function: phpFunction{
|
|
Name: "arrayFunction",
|
|
ReturnType: "array",
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray},
|
|
{Name: "filter", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with nullable array parameter",
|
|
function: phpFunction{
|
|
Name: "nullableArrayFunction",
|
|
ReturnType: "string",
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray, IsNullable: true},
|
|
{Name: "name", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with callable parameter",
|
|
function: phpFunction{
|
|
Name: "callableFunction",
|
|
ReturnType: "array",
|
|
Params: []phpParameter{
|
|
{Name: "data", PhpType: phpArray},
|
|
{Name: "callback", PhpType: phpCallable},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid function with nullable callable parameter",
|
|
function: phpFunction{
|
|
Name: "nullableCallableFunction",
|
|
ReturnType: "string",
|
|
Params: []phpParameter{
|
|
{Name: "callback", PhpType: phpCallable, IsNullable: true},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty function name",
|
|
function: phpFunction{
|
|
Name: "",
|
|
ReturnType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid function name - starts with number",
|
|
function: phpFunction{
|
|
Name: "123invalid",
|
|
ReturnType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid function name - contains special chars",
|
|
function: phpFunction{
|
|
Name: "invalid-name",
|
|
ReturnType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid parameter name",
|
|
function: phpFunction{
|
|
Name: "validName",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "123invalid", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "empty parameter name",
|
|
function: phpFunction{
|
|
Name: "validName",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateFunction(tt.function)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateFunction() should return an error for function %s", tt.function.Name)
|
|
} else {
|
|
assert.NoError(t, err, "validateFunction() should not return an error for function %s", tt.function.Name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateReturnType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
returnType string
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid string type",
|
|
returnType: "string",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid int type",
|
|
returnType: "int",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid array type",
|
|
returnType: "array",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid bool type",
|
|
returnType: "bool",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid float type",
|
|
returnType: "float",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid void type",
|
|
returnType: "void",
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid return type",
|
|
returnType: "invalidType",
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "empty return type",
|
|
returnType: "",
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "case sensitive - String should be invalid",
|
|
returnType: "String",
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateReturnType(phpType(tt.returnType))
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateReturnType(%s) should return an error", tt.returnType)
|
|
} else {
|
|
assert.NoError(t, err, "validateReturnType(%s) should not return an error", tt.returnType)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateClassProperty(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
prop phpClassProperty
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid property",
|
|
prop: phpClassProperty{
|
|
Name: "validProperty",
|
|
PhpType: phpString,
|
|
GoType: "string",
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable property",
|
|
prop: phpClassProperty{
|
|
Name: "nullableProperty",
|
|
PhpType: phpInt,
|
|
GoType: "*int",
|
|
IsNullable: true,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty property name",
|
|
prop: phpClassProperty{
|
|
Name: "",
|
|
PhpType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid property name",
|
|
prop: phpClassProperty{
|
|
Name: "123invalid",
|
|
PhpType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid property type",
|
|
prop: phpClassProperty{
|
|
Name: "validName",
|
|
PhpType: phpType("invalidType"),
|
|
},
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateClassProperty(tt.prop)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateClassProperty() should return an error")
|
|
} else {
|
|
assert.NoError(t, err, "validateClassProperty() should not return an error")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateParameter(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
param phpParameter
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid string parameter",
|
|
param: phpParameter{
|
|
Name: "validParam",
|
|
PhpType: phpString,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable parameter",
|
|
param: phpParameter{
|
|
Name: "nullableParam",
|
|
PhpType: phpInt,
|
|
IsNullable: true,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid parameter with default",
|
|
param: phpParameter{
|
|
Name: "defaultParam",
|
|
PhpType: phpString,
|
|
HasDefault: true,
|
|
DefaultValue: "hello",
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid array parameter",
|
|
param: phpParameter{
|
|
Name: "arrayParam",
|
|
PhpType: phpArray,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable array parameter",
|
|
param: phpParameter{
|
|
Name: "nullableArrayParam",
|
|
PhpType: phpArray,
|
|
IsNullable: true,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid callable parameter",
|
|
param: phpParameter{
|
|
Name: "callbackParam",
|
|
PhpType: phpCallable,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable callable parameter",
|
|
param: phpParameter{
|
|
Name: "nullableCallbackParam",
|
|
PhpType: "callable",
|
|
IsNullable: true,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty parameter name",
|
|
param: phpParameter{
|
|
Name: "",
|
|
PhpType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid parameter name",
|
|
param: phpParameter{
|
|
Name: "123invalid",
|
|
PhpType: phpString,
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid parameter type",
|
|
param: phpParameter{
|
|
Name: "validName",
|
|
PhpType: phpType("invalidType"),
|
|
},
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateParameter(tt.param)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateParameter() should return an error")
|
|
} else {
|
|
assert.NoError(t, err, "validateParameter() should not return an error")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateClass(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
class phpClass
|
|
expectError bool
|
|
}{
|
|
{
|
|
name: "valid class",
|
|
class: phpClass{
|
|
Name: "ValidClass",
|
|
GoStruct: "ValidStruct",
|
|
Properties: []phpClassProperty{
|
|
{Name: "name", PhpType: phpString},
|
|
{Name: "age", PhpType: phpInt},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid class with nullable properties",
|
|
class: phpClass{
|
|
Name: "NullableClass",
|
|
GoStruct: "NullableStruct",
|
|
Properties: []phpClassProperty{
|
|
{Name: "required", PhpType: phpString, IsNullable: false},
|
|
{Name: "optional", PhpType: phpString, IsNullable: true},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "empty class name",
|
|
class: phpClass{
|
|
Name: "",
|
|
GoStruct: "ValidStruct",
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid class name",
|
|
class: phpClass{
|
|
Name: "123InvalidClass",
|
|
GoStruct: "ValidStruct",
|
|
},
|
|
expectError: true,
|
|
},
|
|
{
|
|
name: "invalid property",
|
|
class: phpClass{
|
|
Name: "ValidClass",
|
|
GoStruct: "ValidStruct",
|
|
Properties: []phpClassProperty{
|
|
{Name: "123invalid", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateClass(tt.class)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateClass() should return an error")
|
|
} else {
|
|
assert.NoError(t, err, "validateClass() should not return an error")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateTypes(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
function phpFunction
|
|
expectError bool
|
|
errorMsg string
|
|
}{
|
|
{
|
|
name: "valid scalar parameters only",
|
|
function: phpFunction{
|
|
Name: "validFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "stringParam", PhpType: phpString},
|
|
{Name: "intParam", PhpType: phpInt},
|
|
{Name: "floatParam", PhpType: phpFloat},
|
|
{Name: "boolParam", PhpType: phpBool},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable scalar parameters",
|
|
function: phpFunction{
|
|
Name: "nullableFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "stringParam", PhpType: phpString, IsNullable: true},
|
|
{Name: "intParam", PhpType: phpInt, IsNullable: true},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid void return type",
|
|
function: phpFunction{
|
|
Name: "voidFunction",
|
|
ReturnType: phpVoid,
|
|
Params: []phpParameter{
|
|
{Name: "stringParam", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid array parameter and return",
|
|
function: phpFunction{
|
|
Name: "arrayFunction",
|
|
ReturnType: phpArray,
|
|
Params: []phpParameter{
|
|
{Name: "arrayParam", PhpType: phpArray},
|
|
{Name: "stringParam", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable array parameter",
|
|
function: phpFunction{
|
|
Name: "nullableArrayFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "arrayParam", PhpType: phpArray, IsNullable: true},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid callable parameter",
|
|
function: phpFunction{
|
|
Name: "callableFunction",
|
|
ReturnType: "array",
|
|
Params: []phpParameter{
|
|
{Name: "callbackParam", PhpType: phpCallable},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable callable parameter",
|
|
function: phpFunction{
|
|
Name: "nullableCallableFunction",
|
|
ReturnType: "string",
|
|
Params: []phpParameter{
|
|
{Name: "callbackParam", PhpType: phpCallable, IsNullable: true},
|
|
},
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "invalid object parameter",
|
|
function: phpFunction{
|
|
Name: "objectFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "objectParam", PhpType: phpObject},
|
|
},
|
|
},
|
|
expectError: true,
|
|
errorMsg: `parameter 1 "objectParam" has unsupported type "object"`,
|
|
},
|
|
{
|
|
name: "invalid object return type",
|
|
function: phpFunction{
|
|
Name: "objectReturnFunction",
|
|
ReturnType: phpObject,
|
|
Params: []phpParameter{
|
|
{Name: "stringParam", PhpType: phpString},
|
|
},
|
|
},
|
|
expectError: true,
|
|
errorMsg: `return type "object" is not supported`,
|
|
},
|
|
{
|
|
name: "mixed scalar and invalid parameters",
|
|
function: phpFunction{
|
|
Name: "mixedFunction",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "validParam", PhpType: phpString},
|
|
{Name: "invalidParam", PhpType: phpObject},
|
|
{Name: "anotherValidParam", PhpType: phpInt},
|
|
},
|
|
},
|
|
expectError: true,
|
|
errorMsg: `parameter 2 "invalidParam" has unsupported type "object"`,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateTypes(tt.function)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateTypes() should return an error for function %s", tt.function.Name)
|
|
assert.Contains(t, err.Error(), tt.errorMsg, "Error message should contain expected text")
|
|
} else {
|
|
assert.NoError(t, err, "validateTypes() should not return an error for function %s", tt.function.Name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateGoFunctionSignature(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
phpFunc phpFunction
|
|
expectError bool
|
|
errorMsg string
|
|
}{
|
|
{
|
|
name: "valid Go function signature",
|
|
phpFunc: phpFunction{
|
|
Name: "testFunc",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "name", PhpType: phpString},
|
|
{Name: "count", PhpType: phpInt},
|
|
},
|
|
GoFunction: `func testFunc(name *C.zend_string, count int64) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid void return type",
|
|
phpFunc: phpFunction{
|
|
Name: "voidFunc",
|
|
ReturnType: phpVoid,
|
|
Params: []phpParameter{
|
|
{Name: "message", PhpType: phpString},
|
|
},
|
|
GoFunction: `func voidFunc(message *C.zend_string) {
|
|
// Do something
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "no Go function provided",
|
|
phpFunc: phpFunction{
|
|
Name: "noGoFunc",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{},
|
|
GoFunction: "",
|
|
},
|
|
expectError: true,
|
|
errorMsg: "no Go function found",
|
|
},
|
|
{
|
|
name: "parameter count mismatch",
|
|
phpFunc: phpFunction{
|
|
Name: "countMismatch",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "param1", PhpType: phpString},
|
|
{Name: "param2", PhpType: phpInt},
|
|
},
|
|
GoFunction: `func countMismatch(param1 *C.zend_string) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: true,
|
|
errorMsg: "parameter count mismatch: PHP function has 2 parameters (expecting 2 Go parameters) but Go function has 1",
|
|
},
|
|
{
|
|
name: "parameter type mismatch",
|
|
phpFunc: phpFunction{
|
|
Name: "typeMismatch",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "name", PhpType: phpString},
|
|
{Name: "count", PhpType: phpInt},
|
|
},
|
|
GoFunction: `func typeMismatch(name *C.zend_string, count string) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: true,
|
|
errorMsg: `parameter 2 type mismatch: PHP "int" requires Go type "int64" but found "string"`,
|
|
},
|
|
{
|
|
name: "return type mismatch",
|
|
phpFunc: phpFunction{
|
|
Name: "returnMismatch",
|
|
ReturnType: phpInt,
|
|
Params: []phpParameter{
|
|
{Name: "value", PhpType: phpString},
|
|
},
|
|
GoFunction: `func returnMismatch(value *C.zend_string) string {
|
|
return ""
|
|
}`,
|
|
},
|
|
expectError: true,
|
|
errorMsg: `return type mismatch: PHP "int" requires Go return type "int64" but found "string"`,
|
|
},
|
|
{
|
|
name: "valid bool parameter and return",
|
|
phpFunc: phpFunction{
|
|
Name: "boolFunc",
|
|
ReturnType: phpBool,
|
|
Params: []phpParameter{
|
|
{Name: "flag", PhpType: phpBool},
|
|
},
|
|
GoFunction: `func boolFunc(flag bool) bool {
|
|
return flag
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid float parameter and return",
|
|
phpFunc: phpFunction{
|
|
Name: "floatFunc",
|
|
ReturnType: phpFloat,
|
|
Params: []phpParameter{
|
|
{Name: "value", PhpType: phpFloat},
|
|
},
|
|
GoFunction: `func floatFunc(value float64) float64 {
|
|
return value * 2.0
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid array parameter and return",
|
|
phpFunc: phpFunction{
|
|
Name: "arrayFunc",
|
|
ReturnType: phpArray,
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray},
|
|
},
|
|
GoFunction: `func arrayFunc(items *C.zend_array) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable array parameter",
|
|
phpFunc: phpFunction{
|
|
Name: "nullableArrayFunc",
|
|
ReturnType: phpString,
|
|
Params: []phpParameter{
|
|
{Name: "items", PhpType: phpArray, IsNullable: true},
|
|
{Name: "name", PhpType: phpString},
|
|
},
|
|
GoFunction: `func nullableArrayFunc(items *C.zend_array, name *C.zend_string) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "mixed array and scalar parameters",
|
|
phpFunc: phpFunction{
|
|
Name: "mixedFunc",
|
|
ReturnType: phpArray,
|
|
Params: []phpParameter{
|
|
{Name: "data", PhpType: phpArray},
|
|
{Name: "filter", PhpType: phpString},
|
|
{Name: "limit", PhpType: phpInt},
|
|
},
|
|
GoFunction: `func mixedFunc(data *C.zend_array, filter *C.zend_string, limit int64) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid callable parameter",
|
|
phpFunc: phpFunction{
|
|
Name: "callableFunc",
|
|
ReturnType: "array",
|
|
Params: []phpParameter{
|
|
{Name: "callback", PhpType: phpCallable},
|
|
},
|
|
GoFunction: `func callableFunc(callback *C.zval) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "valid nullable callable parameter",
|
|
phpFunc: phpFunction{
|
|
Name: "nullableCallableFunc",
|
|
ReturnType: "string",
|
|
Params: []phpParameter{
|
|
{Name: "callback", PhpType: phpCallable, IsNullable: true},
|
|
},
|
|
GoFunction: `func nullableCallableFunc(callback *C.zval) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "mixed callable and other parameters",
|
|
phpFunc: phpFunction{
|
|
Name: "mixedCallableFunc",
|
|
ReturnType: "array",
|
|
Params: []phpParameter{
|
|
{Name: "data", PhpType: phpArray},
|
|
{Name: "callback", PhpType: phpCallable},
|
|
{Name: "options", PhpType: "int"},
|
|
},
|
|
GoFunction: `func mixedCallableFunc(data *C.zend_array, callback *C.zval, options int64) unsafe.Pointer {
|
|
return nil
|
|
}`,
|
|
},
|
|
expectError: false,
|
|
},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validator.validateGoFunctionSignatureWithOptions(tt.phpFunc, false)
|
|
|
|
if tt.expectError {
|
|
assert.Error(t, err, "validateGoFunctionSignature() should return an error for function %s", tt.phpFunc.Name)
|
|
assert.Contains(t, err.Error(), tt.errorMsg, "Error message should contain expected text")
|
|
} else {
|
|
assert.NoError(t, err, "validateGoFunctionSignature() should not return an error for function %s", tt.phpFunc.Name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPhpTypeToGoType(t *testing.T) {
|
|
tests := []struct {
|
|
phpType string
|
|
isNullable bool
|
|
expected string
|
|
}{
|
|
{"string", false, "*C.zend_string"},
|
|
{"string", true, "*C.zend_string"},
|
|
{"int", false, "int64"},
|
|
{"int", true, "*int64"},
|
|
{"float", false, "float64"},
|
|
{"float", true, "*float64"},
|
|
{"bool", false, "bool"},
|
|
{"bool", true, "*bool"},
|
|
{"array", false, "*C.zend_array"},
|
|
{"array", true, "*C.zend_array"},
|
|
{"callable", false, "*C.zval"},
|
|
{"callable", true, "*C.zval"},
|
|
{"unknown", false, "any"},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.phpType, func(t *testing.T) {
|
|
result := validator.phpTypeToGoType(phpType(tt.phpType), tt.isNullable)
|
|
assert.Equal(t, tt.expected, result, "phpTypeToGoType(%s, %v) should return %s", tt.phpType, tt.isNullable, tt.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPhpReturnTypeToGoType(t *testing.T) {
|
|
tests := []struct {
|
|
phpReturnType string
|
|
expected string
|
|
}{
|
|
{"void", ""},
|
|
{"void", ""},
|
|
{"string", "unsafe.Pointer"},
|
|
{"string", "unsafe.Pointer"},
|
|
{"int", "int64"},
|
|
{"int", "int64"},
|
|
{"float", "float64"},
|
|
{"float", "float64"},
|
|
{"bool", "bool"},
|
|
{"bool", "bool"},
|
|
{"array", "unsafe.Pointer"},
|
|
{"array", "unsafe.Pointer"},
|
|
{"unknown", "any"},
|
|
}
|
|
|
|
validator := Validator{}
|
|
for _, tt := range tests {
|
|
t.Run(tt.phpReturnType, func(t *testing.T) {
|
|
result := validator.phpReturnTypeToGoType(phpType(tt.phpReturnType))
|
|
assert.Equal(t, tt.expected, result, "phpReturnTypeToGoType(%s) should return %s", tt.phpReturnType, tt.expected)
|
|
})
|
|
}
|
|
}
|