getMessage()}\n"; $testsFailed++; } } // Test 1: Create from array test('Create from array', function () { $payload = EventPayload::fromArray(['key' => 'value', 'number' => 42]); assert($payload->get('key') === 'value'); assert($payload->get('number') === 42); }); // Test 2: Create empty test('Create empty', function () { $payload = EventPayload::empty(); assert($payload->isEmpty() === true); assert($payload->size() === 0); }); // Test 3: Get with default test('Get with default', function () { $payload = EventPayload::fromArray(['key' => 'value']); assert($payload->get('missing', 'default') === 'default'); }); // Test 4: Has key test('Has key', function () { $payload = EventPayload::fromArray(['key' => 'value']); assert($payload->has('key') === true); assert($payload->has('missing') === false); }); // Test 5: Get string test('Get string', function () { $payload = EventPayload::fromArray(['name' => 'John', 'age' => 30]); assert($payload->getString('name') === 'John'); assert($payload->getString('age') === '30'); // Type coercion }); // Test 6: Require string test('Require string', function () { $payload = EventPayload::fromArray(['name' => 'John']); assert($payload->requireString('name') === 'John'); }); // Test 7: Require string throws on missing test('Require string throws on missing', function () { $payload = EventPayload::empty(); try { $payload->requireString('missing'); assert(false, 'Should have thrown exception'); } catch (InvalidArgumentException $e) { assert(str_contains($e->getMessage(), 'missing')); } }); // Test 8: Get int test('Get int', function () { $payload = EventPayload::fromArray(['count' => 42, 'string_num' => '100']); assert($payload->getInt('count') === 42); assert($payload->getInt('string_num') === 100); // Type coercion }); // Test 9: Get float test('Get float', function () { $payload = EventPayload::fromArray(['price' => 19.99, 'integer' => 42]); assert($payload->getFloat('price') === 19.99); assert($payload->getFloat('integer') === 42.0); // Type coercion }); // Test 10: Get bool test('Get bool', function () { $payload = EventPayload::fromArray(['active' => true, 'inactive' => false]); assert($payload->getBool('active') === true); assert($payload->getBool('inactive') === false); }); // Test 11: Get array test('Get array', function () { $payload = EventPayload::fromArray(['items' => ['a', 'b', 'c']]); assert($payload->getArray('items') === ['a', 'b', 'c']); }); // Test 12: With (immutable update) test('With (immutable update)', function () { $payload1 = EventPayload::fromArray(['key' => 'value']); $payload2 = $payload1->with('new', 'data'); assert($payload1->has('new') === false); // Original unchanged assert($payload2->has('new') === true); assert($payload2->get('key') === 'value'); // Old data preserved }); // Test 13: WithMany test('WithMany', function () { $payload1 = EventPayload::fromArray(['a' => 1]); $payload2 = $payload1->withMany(['b' => 2, 'c' => 3]); assert($payload2->get('a') === 1); assert($payload2->get('b') === 2); assert($payload2->get('c') === 3); }); // Test 14: Without test('Without', function () { $payload1 = EventPayload::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $payload2 = $payload1->without('b'); assert($payload1->has('b') === true); // Original unchanged assert($payload2->has('b') === false); assert($payload2->get('a') === 1); }); // Test 15: Only test('Only', function () { $payload1 = EventPayload::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $payload2 = $payload1->only(['a', 'c']); assert($payload2->size() === 2); assert($payload2->has('a') === true); assert($payload2->has('b') === false); assert($payload2->has('c') === true); }); // Test 16: Except test('Except', function () { $payload1 = EventPayload::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $payload2 = $payload1->except(['b']); assert($payload2->size() === 2); assert($payload2->has('a') === true); assert($payload2->has('b') === false); assert($payload2->has('c') === true); }); // Test 17: Merge test('Merge', function () { $payload1 = EventPayload::fromArray(['a' => 1, 'b' => 2]); $payload2 = EventPayload::fromArray(['c' => 3, 'd' => 4]); $merged = $payload1->merge($payload2); assert($merged->size() === 4); assert($merged->get('a') === 1); assert($merged->get('d') === 4); }); // Test 18: Equals test('Equals', function () { $payload1 = EventPayload::fromArray(['a' => 1, 'b' => 2]); $payload2 = EventPayload::fromArray(['a' => 1, 'b' => 2]); $payload3 = EventPayload::fromArray(['a' => 1, 'b' => 3]); assert($payload1->equals($payload2) === true); assert($payload1->equals($payload3) === false); }); // Test 19: Keys test('Keys', function () { $payload = EventPayload::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $keys = $payload->keys(); assert(count($keys) === 3); assert(in_array('a', $keys)); assert(in_array('b', $keys)); assert(in_array('c', $keys)); }); // Test 20: ToArray test('ToArray', function () { $data = ['key' => 'value', 'number' => 42]; $payload = EventPayload::fromArray($data); assert($payload->toArray() === $data); }); // Test 21: Validation - non-string keys test('Validation rejects non-string keys', function () { try { EventPayload::fromArray([0 => 'value', 'key' => 'data']); assert(false, 'Should have thrown exception'); } catch (InvalidArgumentException $e) { assert(str_contains($e->getMessage(), 'must be strings')); } }); echo "\n"; echo "==================================\n"; echo "Tests passed: {$testsPassed}\n"; echo "Tests failed: {$testsFailed}\n"; echo "==================================\n"; if ($testsFailed > 0) { exit(1); } echo "\nāœ… All EventPayload tests passed!\n";