Files
frankenphp/types_test.go
Alliballibaba d54f736db7 simplifications
2025-10-26 20:52:19 +01:00

160 lines
4.3 KiB
Go

package frankenphp
import (
"errors"
"log/slog"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/exp/zapslog"
"go.uber.org/zap/zaptest"
)
// execute the function on a PHP thread directly
// this is necessary if tests make use of PHP's internal allocation
func testOnDummyPHPThread(t *testing.T, cb func()) {
t.Helper()
logger = slog.New(zapslog.NewHandler(zaptest.NewLogger(t).Core()))
assert.NoError(t, Init(
WithWorkers("tw", "./testdata/tasks/task-worker.php", 1, AsTaskWorker(true, 0)),
WithNumThreads(2),
WithLogger(logger),
))
defer Shutdown()
assert.NoError(t, executeOnPHPThread(cb, "tw"))
}
// executeOnPHPThread executes the callback func() directly on a task worker thread
// useful for testing purposes when dealing with PHP allocations
func executeOnPHPThread(callback func(), taskWorkerName string) error {
tw := getTaskWorkerByName(taskWorkerName)
if tw == nil {
return errors.New("no task worker found with name " + taskWorkerName)
}
return tw.dispatch(&pendingTask{callback: callback})
}
func TestGoString(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalString := "Hello, World!"
phpString := PHPString(originalString, false)
defer zendStringRelease(phpString)
assert.Equal(t, originalString, GoString(phpString), "string -> zend_string -> string should yield an equal string")
})
}
func TestPHPMap(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalMap := map[string]string{
"foo1": "bar1",
"foo2": "bar2",
}
phpArray := PHPMap(originalMap)
defer zvalPtrDtor(phpArray)
convertedMap, err := GoMap[string](phpArray)
require.NoError(t, err)
assert.Equal(t, originalMap, convertedMap, "associative array should be equal after conversion")
})
}
func TestOrderedPHPAssociativeArray(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalArray := AssociativeArray[string]{
Map: map[string]string{
"foo1": "bar1",
"foo2": "bar2",
},
Order: []string{"foo2", "foo1"},
}
phpArray := PHPAssociativeArray(originalArray)
defer zvalPtrDtor(phpArray)
convertedArray, err := GoAssociativeArray[string](phpArray)
require.NoError(t, err)
assert.Equal(t, originalArray, convertedArray, "associative array should be equal after conversion")
})
}
func TestPHPPackedArray(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalSlice := []string{"bar1", "bar2"}
phpArray := PHPPackedArray(originalSlice)
defer zvalPtrDtor(phpArray)
convertedSlice, err := GoPackedArray[string](phpArray)
require.NoError(t, err)
assert.Equal(t, originalSlice, convertedSlice, "slice should be equal after conversion")
})
}
func TestPHPPackedArrayToGoMap(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalSlice := []string{"bar1", "bar2"}
expectedMap := map[string]string{
"0": "bar1",
"1": "bar2",
}
phpArray := PHPPackedArray(originalSlice)
defer zvalPtrDtor(phpArray)
convertedMap, err := GoMap[string](phpArray)
require.NoError(t, err)
assert.Equal(t, expectedMap, convertedMap, "convert a packed to an associative array")
})
}
func TestPHPAssociativeArrayToPacked(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalArray := AssociativeArray[string]{
Map: map[string]string{
"foo1": "bar1",
"foo2": "bar2",
},
Order: []string{"foo1", "foo2"},
}
expectedSlice := []string{"bar1", "bar2"}
phpArray := PHPAssociativeArray(originalArray)
defer zvalPtrDtor(phpArray)
convertedSlice, err := GoPackedArray[string](phpArray)
require.NoError(t, err)
assert.Equal(t, expectedSlice, convertedSlice, "convert an associative array to a slice")
})
}
func TestNestedMixedArray(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalArray := map[string]any{
"string": "value",
"int": int64(123),
"float": 1.2,
"true": true,
"false": false,
"nil": nil,
"packedArray": []any{"bar1", "bar2"},
"associativeArray": AssociativeArray[any]{
Map: map[string]any{"foo1": "bar1", "foo2": "bar2"},
Order: []string{"foo2", "foo1"},
},
}
phpArray := PHPMap(originalArray)
defer zvalPtrDtor(phpArray)
convertedArray, err := GoMap[any](phpArray)
require.NoError(t, err)
assert.Equal(t, originalArray, convertedArray, "nested mixed array should be equal after conversion")
})
}