|
| 1 | +<?php |
| 2 | + |
| 3 | +// Exercises frankenphp_test_persist_roundtrip (only registered when |
| 4 | +// FRANKENPHP_TEST_HOOKS is defined at build time). The script runs as a |
| 5 | +// plain non-worker request; the Go harness asserts the combined output. |
| 6 | + |
| 7 | +enum Status: string { |
| 8 | + case Active = 'active'; |
| 9 | + case Paused = 'paused'; |
| 10 | +} |
| 11 | + |
| 12 | +function same(mixed $actual, mixed $expected, string $label): void { |
| 13 | + if ($actual !== $expected) { |
| 14 | + echo "FAIL $label: expected "; |
| 15 | + var_export($expected); |
| 16 | + echo ' got '; |
| 17 | + var_export($actual); |
| 18 | + echo "\n"; |
| 19 | + return; |
| 20 | + } |
| 21 | + echo "OK $label\n"; |
| 22 | +} |
| 23 | + |
| 24 | +$rt = 'frankenphp_test_persist_roundtrip'; |
| 25 | +if (!function_exists($rt)) { |
| 26 | + echo "SKIP frankenphp_test_persist_roundtrip not registered\n"; |
| 27 | + return; |
| 28 | +} |
| 29 | + |
| 30 | +// Scalars. |
| 31 | +same($rt(null), null, 'null'); |
| 32 | +same($rt(false), false, 'false'); |
| 33 | +same($rt(true), true, 'true'); |
| 34 | +same($rt(0), 0, 'int zero'); |
| 35 | +same($rt(42), 42, 'int'); |
| 36 | +same($rt(-1), -1, 'int negative'); |
| 37 | +same($rt(1.5), 1.5, 'float'); |
| 38 | +same($rt(''), '', 'empty string'); |
| 39 | +same($rt('hello'), 'hello', 'short string'); |
| 40 | + |
| 41 | +// Long (non-interned) string: forces the allocation path. |
| 42 | +$long = str_repeat('x', 1024); |
| 43 | +same($rt($long), $long, 'long string'); |
| 44 | + |
| 45 | +// Nested arrays, mixed keys. |
| 46 | +$arr = [ |
| 47 | + 'name' => 'alice', |
| 48 | + 'age' => 30, |
| 49 | + 'tags' => ['admin', 'editor'], |
| 50 | + 'meta' => ['created' => 1234567890, 'flags' => [true, false, null]], |
| 51 | + 0 => 'first', |
| 52 | + 1 => 'second', |
| 53 | +]; |
| 54 | +same($rt($arr), $arr, 'nested array'); |
| 55 | + |
| 56 | +// Enum roundtrip: identity (===) must be preserved because the enum is |
| 57 | +// re-resolved to the same singleton case on the read side. |
| 58 | +same($rt(Status::Active), Status::Active, 'enum active'); |
| 59 | +same($rt(Status::Paused), Status::Paused, 'enum paused'); |
| 60 | + |
| 61 | +// Array containing an enum. |
| 62 | +same( |
| 63 | + $rt(['status' => Status::Active, 'count' => 7]), |
| 64 | + ['status' => Status::Active, 'count' => 7], |
| 65 | + 'array with enum', |
| 66 | +); |
| 67 | + |
| 68 | +// Invalid inputs throw LogicException. |
| 69 | +try { |
| 70 | + $rt(new stdClass()); |
| 71 | + echo "FAIL stdClass should throw\n"; |
| 72 | +} catch (\LogicException) { |
| 73 | + echo "OK stdClass rejected\n"; |
| 74 | +} |
| 75 | + |
| 76 | +try { |
| 77 | + $rt(fopen('php://memory', 'r')); |
| 78 | + echo "FAIL resource should throw\n"; |
| 79 | +} catch (\LogicException) { |
| 80 | + echo "OK resource rejected\n"; |
| 81 | +} |
| 82 | + |
| 83 | +try { |
| 84 | + $rt(['ok' => 1, 'bad' => new stdClass()]); |
| 85 | + echo "FAIL nested stdClass should throw\n"; |
| 86 | +} catch (\LogicException) { |
| 87 | + echo "OK nested stdClass rejected\n"; |
| 88 | +} |
0 commit comments