#!/usr/bin/env php 0, 'label' => 'Counter', 'enabled' => true, ]); echo " ✓ Created ComponentData with 3 keys\n"; echo " ✓ Count: " . $data->count() . "\n\n"; // Test 2: Create empty echo "Test 2: Create empty ComponentData\n"; $empty = ComponentData::empty(); echo " ✓ isEmpty(): " . ($empty->isEmpty() ? 'YES' : 'NO') . "\n"; echo " ✓ count(): " . $empty->count() . "\n\n"; // Test 3: Get values echo "Test 3: Get values with get()\n"; $data = ComponentData::fromArray([ 'user_id' => 123, 'email' => 'test@example.com', 'roles' => ['admin', 'user'], ]); echo " ✓ user_id: " . $data->get('user_id') . "\n"; echo " ✓ email: " . $data->get('email') . "\n"; echo " ✓ missing key with default: " . $data->get('missing', 'default') . "\n\n"; // Test 4: Check key existence echo "Test 4: Check key existence with has()\n"; echo " ✓ Has 'user_id': " . ($data->has('user_id') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'missing': " . ($data->has('missing') ? 'YES' : 'NO') . "\n\n"; // Test 5: toArray() echo "Test 5: Convert to array with toArray()\n"; $array = $data->toArray(); echo " ✓ Array keys: " . implode(', ', array_keys($array)) . "\n"; echo " ✓ Is array: " . (is_array($array) ? 'YES' : 'NO') . "\n\n"; // Test 6: Immutable with() echo "Test 6: Immutable with() method\n"; $original = ComponentData::fromArray(['count' => 0]); $updated = $original->with('count', 5); echo " ✓ Original count: " . $original->get('count') . "\n"; echo " ✓ Updated count: " . $updated->get('count') . "\n"; echo " ✓ Different instances: " . ($original !== $updated ? 'YES' : 'NO') . "\n\n"; // Test 7: withMany() echo "Test 7: Update multiple keys with withMany()\n"; $data = ComponentData::fromArray(['a' => 1, 'b' => 2]); $updated = $data->withMany(['b' => 20, 'c' => 30]); echo " ✓ Original count: " . $data->count() . "\n"; echo " ✓ Updated count: " . $updated->count() . "\n"; echo " ✓ Updated 'b': " . $updated->get('b') . "\n"; echo " ✓ New 'c': " . $updated->get('c') . "\n\n"; // Test 8: without() echo "Test 8: Remove key with without()\n"; $data = ComponentData::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $removed = $data->without('b'); echo " ✓ Original has 'b': " . ($data->has('b') ? 'YES' : 'NO') . "\n"; echo " ✓ Removed has 'b': " . ($removed->has('b') ? 'YES' : 'NO') . "\n"; echo " ✓ Removed count: " . $removed->count() . "\n\n"; // Test 9: withoutMany() echo "Test 9: Remove multiple keys with withoutMany()\n"; $data = ComponentData::fromArray(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]); $removed = $data->withoutMany(['b', 'd']); echo " ✓ Original count: " . $data->count() . "\n"; echo " ✓ Removed count: " . $removed->count() . "\n"; echo " ✓ Has 'a': " . ($removed->has('a') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'b': " . ($removed->has('b') ? 'YES' : 'NO') . "\n\n"; // Test 10: keys() echo "Test 10: Get all keys with keys()\n"; $data = ComponentData::fromArray(['name' => 'John', 'age' => 30, 'city' => 'NYC']); $keys = $data->keys(); echo " ✓ Keys: " . implode(', ', $keys) . "\n"; echo " ✓ Keys count: " . count($keys) . "\n\n"; // Test 11: merge() echo "Test 11: Merge two ComponentData with merge()\n"; $data1 = ComponentData::fromArray(['a' => 1, 'b' => 2]); $data2 = ComponentData::fromArray(['b' => 20, 'c' => 30]); $merged = $data1->merge($data2); echo " ✓ Merged count: " . $merged->count() . "\n"; echo " ✓ Merged 'a': " . $merged->get('a') . "\n"; echo " ✓ Merged 'b': " . $merged->get('b') . " (should be 20)\n"; echo " ✓ Merged 'c': " . $merged->get('c') . "\n\n"; // Test 12: only() echo "Test 12: Filter keys with only()\n"; $data = ComponentData::fromArray([ 'name' => 'John', 'age' => 30, 'city' => 'NYC', 'country' => 'USA', ]); $filtered = $data->only(['name', 'city']); echo " ✓ Original count: " . $data->count() . "\n"; echo " ✓ Filtered count: " . $filtered->count() . "\n"; echo " ✓ Has 'name': " . ($filtered->has('name') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'age': " . ($filtered->has('age') ? 'YES' : 'NO') . "\n\n"; // Test 13: equals() echo "Test 13: Check equality with equals()\n"; $data1 = ComponentData::fromArray(['a' => 1, 'b' => 2]); $data2 = ComponentData::fromArray(['a' => 1, 'b' => 2]); $data3 = ComponentData::fromArray(['a' => 1, 'b' => 3]); echo " ✓ data1 equals data2: " . ($data1->equals($data2) ? 'YES' : 'NO') . "\n"; echo " ✓ data1 equals data3: " . ($data1->equals($data3) ? 'YES' : 'NO') . "\n\n"; // Test 14: Exception for non-string keys echo "Test 14: Throw exception for non-string keys\n"; try { ComponentData::fromArray([0 => 'value', 1 => 'another']); echo " ✗ Should have thrown exception\n"; } catch (InvalidArgumentException $e) { echo " ✓ Exception thrown: " . $e->getMessage() . "\n"; } echo "\n"; // Test 15: Complex nested data echo "Test 15: Handle complex nested data\n"; $data = ComponentData::fromArray([ 'user' => [ 'id' => 123, 'profile' => [ 'name' => 'John', 'avatar' => 'avatar.jpg', ], ], 'settings' => [ 'theme' => 'dark', 'notifications' => true, ], ]); echo " ✓ Created with nested data\n"; echo " ✓ Top-level keys: " . implode(', ', $data->keys()) . "\n"; $userArray = $data->get('user'); echo " ✓ User ID: " . $userArray['id'] . "\n"; echo " ✓ User profile name: " . $userArray['profile']['name'] . "\n\n"; echo "===================================\n"; echo "✅ All ComponentData tests passed!\n"; } catch (\Throwable $e) { echo "❌ Error: " . $e->getMessage() . "\n"; echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n"; echo " Trace:\n" . $e->getTraceAsString() . "\n"; exit(1); }