#!/usr/bin/env php 123, 'email' => 'test@example.com', 'enabled' => true, ]); echo " ✓ Created with 3 parameters\n"; echo " ✓ Count: " . $params->count() . "\n\n"; // Test 2: Create empty echo "Test 2: Create empty ActionParameters\n"; $empty = ActionParameters::empty(); echo " ✓ isEmpty(): " . ($empty->isEmpty() ? 'YES' : 'NO') . "\n"; echo " ✓ count(): " . $empty->count() . "\n\n"; // Test 3: Get string parameter echo "Test 3: Get string parameter with getString()\n"; $params = ActionParameters::fromArray(['name' => 'John', 'age' => 30]); $name = $params->getString('name'); echo " ✓ name: " . $name . "\n"; echo " ✓ missing with default: " . $params->getString('missing', 'default') . "\n\n"; // Test 4: Require string parameter echo "Test 4: Require string parameter with requireString()\n"; $email = $params->getString('missing', 'default@example.com'); echo " ✓ With default: " . $email . "\n"; try { $params->requireString('missing'); echo " ✗ Should have thrown exception\n"; } catch (InvalidArgumentException $e) { echo " ✓ Exception for missing: " . substr($e->getMessage(), 0, 50) . "...\n"; } echo "\n"; // Test 5: Get integer parameter echo "Test 5: Get integer with getInt()\n"; $params = ActionParameters::fromArray(['count' => 42, 'price' => '99']); echo " ✓ count (int): " . $params->getInt('count') . "\n"; echo " ✓ price (string numeric): " . $params->getInt('price') . "\n"; echo " ✓ missing with default: " . $params->getInt('missing', 0) . "\n\n"; // Test 6: Get float parameter echo "Test 6: Get float with getFloat()\n"; $params = ActionParameters::fromArray(['price' => 19.99, 'discount' => 10]); echo " ✓ price (float): " . $params->getFloat('price') . "\n"; echo " ✓ discount (int to float): " . $params->getFloat('discount') . "\n\n"; // Test 7: Get boolean parameter echo "Test 7: Get boolean with getBool()\n"; $params = ActionParameters::fromArray(['enabled' => true, 'active' => false]); echo " ✓ enabled: " . ($params->getBool('enabled') ? 'true' : 'false') . "\n"; echo " ✓ active: " . ($params->getBool('active') ? 'true' : 'false') . "\n\n"; // Test 8: Get array parameter echo "Test 8: Get array with getArray()\n"; $params = ActionParameters::fromArray([ 'tags' => ['php', 'framework', 'testing'], 'config' => ['debug' => true], ]); $tags = $params->getArray('tags'); echo " ✓ tags: " . implode(', ', $tags) . "\n"; echo " ✓ tags count: " . count($tags) . "\n\n"; // Test 9: Type validation echo "Test 9: Type validation errors\n"; $params = ActionParameters::fromArray(['value' => 'not-a-number']); try { $params->getInt('value'); echo " ✗ Should have thrown exception\n"; } catch (InvalidArgumentException $e) { echo " ✓ Exception for wrong type: " . substr($e->getMessage(), 0, 50) . "...\n"; } echo "\n"; // Test 10: has() echo "Test 10: Check parameter existence with has()\n"; $params = ActionParameters::fromArray(['name' => 'John', 'age' => 30]); echo " ✓ Has 'name': " . ($params->has('name') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'missing': " . ($params->has('missing') ? 'YES' : 'NO') . "\n\n"; // Test 11: keys() echo "Test 11: Get all keys with keys()\n"; $params = ActionParameters::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); $keys = $params->keys(); echo " ✓ Keys: " . implode(', ', $keys) . "\n\n"; // Test 12: only() echo "Test 12: Filter parameters with only()\n"; $params = ActionParameters::fromArray([ 'user_id' => 123, 'email' => 'test@example.com', 'password' => 'secret', 'role' => 'admin', ]); $filtered = $params->only(['user_id', 'email']); echo " ✓ Original count: " . $params->count() . "\n"; echo " ✓ Filtered count: " . $filtered->count() . "\n"; echo " ✓ Has 'email': " . ($filtered->has('email') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'password': " . ($filtered->has('password') ? 'YES' : 'NO') . "\n\n"; // Test 13: except() echo "Test 13: Exclude parameters with except()\n"; $params = ActionParameters::fromArray([ 'name' => 'John', 'password' => 'secret', 'token' => 'abc123', 'role' => 'user', ]); $safe = $params->except(['password', 'token']); echo " ✓ Original count: " . $params->count() . "\n"; echo " ✓ Safe count: " . $safe->count() . "\n"; echo " ✓ Has 'name': " . ($safe->has('name') ? 'YES' : 'NO') . "\n"; echo " ✓ Has 'password': " . ($safe->has('password') ? 'YES' : 'NO') . "\n\n"; // Test 14: equals() echo "Test 14: Check equality with equals()\n"; $params1 = ActionParameters::fromArray(['a' => 1, 'b' => 2]); $params2 = ActionParameters::fromArray(['a' => 1, 'b' => 2]); $params3 = ActionParameters::fromArray(['a' => 1, 'b' => 3]); echo " ✓ params1 equals params2: " . ($params1->equals($params2) ? 'YES' : 'NO') . "\n"; echo " ✓ params1 equals params3: " . ($params1->equals($params3) ? 'YES' : 'NO') . "\n\n"; // Test 15: Exception for non-string keys echo "Test 15: Throw exception for non-string keys\n"; try { ActionParameters::fromArray([0 => 'value', 1 => 'another']); echo " ✗ Should have thrown exception\n"; } catch (InvalidArgumentException $e) { echo " ✓ Exception thrown: " . $e->getMessage() . "\n"; } echo "\n"; // Test 16: Real-world use case echo "Test 16: Real-world component action parameters\n"; $params = ActionParameters::fromArray([ 'tab_id' => 'settings', 'user_id' => 123, 'options' => ['theme' => 'dark', 'lang' => 'de'], 'enabled' => true, ]); echo " ✓ tab_id: " . $params->requireString('tab_id') . "\n"; echo " ✓ user_id: " . $params->requireInt('user_id') . "\n"; $options = $params->getArray('options'); echo " ✓ options theme: " . $options['theme'] . "\n"; echo " ✓ enabled: " . ($params->getBool('enabled') ? 'true' : 'false') . "\n\n"; echo "======================================\n"; echo "✅ All ActionParameters 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); }