Files
frankenphp/types_test.go
Alexander Stecher d540727369 feat:(extgen) make Go arrays more consistent with PHP arrays (#1800)
* Makes go arrays more consistent with PHP arrays.

* NewAssociativeArray.

* linting

* go linting

* Exposes all primitive types.

* Removes pointer alias

* linting

* Optimizes hash update.

* Fixes extgen tests.

* Moves file to tests.

* Fixes suggested by @dunglas.

* Replaces 'interface{}' with 'any'.

* Panics on wrong zval.

* interface improvements as suggested by @dunglas.

* Adjusts docs.

* Adjusts docs.

* Removes PackedArray alias and adjusts docs.

* Updates docs.
2025-08-25 16:24:15 +02:00

128 lines
3.2 KiB
Go

package frankenphp
import (
"io"
"log/slog"
"testing"
"github.com/stretchr/testify/assert"
)
// 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, test func()) {
t.Helper()
logger = slog.New(slog.NewTextHandler(io.Discard, nil))
_, err := initPHPThreads(1, 1, nil) // boot 1 thread
assert.NoError(t, err)
handler := convertToTaskThread(phpThreads[0])
task := newTask(test)
handler.execute(task)
task.waitForCompletion()
drainPHPThreads()
}
func TestGoString(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalString := "Hello, World!"
convertedString := GoString(PHPString(originalString, false))
assert.Equal(t, originalString, convertedString, "string -> zend_string -> string should yield an equal string")
})
}
func TestPHPMap(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalMap := map[string]any{
"foo1": "bar1",
"foo2": "bar2",
}
convertedMap := GoMap(PHPMap(originalMap))
assert.Equal(t, originalMap, convertedMap, "associative array should be equal after conversion")
})
}
func TestOrderedPHPAssociativeArray(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalArray := AssociativeArray{
Map: map[string]any{
"foo1": "bar1",
"foo2": "bar2",
},
Order: []string{"foo2", "foo1"},
}
convertedArray := GoAssociativeArray(PHPAssociativeArray(originalArray))
assert.Equal(t, originalArray, convertedArray, "associative array should be equal after conversion")
})
}
func TestPHPPackedArray(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalSlice := []any{"bar1", "bar2"}
convertedSlice := GoPackedArray(PHPPackedArray(originalSlice))
assert.Equal(t, originalSlice, convertedSlice, "slice should be equal after conversion")
})
}
func TestPHPPackedArrayToGoMap(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalSlice := []any{"bar1", "bar2"}
expectedMap := map[string]any{
"0": "bar1",
"1": "bar2",
}
convertedMap := GoMap(PHPPackedArray(originalSlice))
assert.Equal(t, expectedMap, convertedMap, "convert a packed to an associative array")
})
}
func TestPHPAssociativeArrayToPacked(t *testing.T) {
testOnDummyPHPThread(t, func() {
originalArray := AssociativeArray{
Map: map[string]any{
"foo1": "bar1",
"foo2": "bar2",
},
Order: []string{"foo1", "foo2"},
}
expectedSlice := []any{"bar1", "bar2"}
convertedSlice := GoPackedArray(PHPAssociativeArray(originalArray))
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": float64(1.2),
"true": true,
"false": false,
"nil": nil,
"packedArray": []any{"bar1", "bar2"},
"associativeArray": AssociativeArray{
Map: map[string]any{"foo1": "bar1", "foo2": "bar2"},
Order: []string{"foo2", "foo1"},
},
}
convertedArray := GoMap(PHPMap(originalArray))
assert.Equal(t, originalArray, convertedArray, "nested mixed array should be equal after conversion")
})
}