singleton(Cache::class, $cache); $container->singleton(Clock::class, $clock); $container->singleton(PathProvider::class, $pathProvider); // Bootstrap discovery $bootstrapper = new DiscoveryServiceBootstrapper($container, $clock); $registry = $bootstrapper->performBootstrap($pathProvider, $cache, null); echo "✓ Discovery System bootstrapped\n"; echo " - Total discovered items: " . $registry->count() . "\n\n"; // 2. Create DataProviderResolver with discovery echo "2. Creating DataProviderResolver...\n"; // Create mock discovery service that wraps the registry $mockDiscovery = new class ($registry) { public function __construct( private \App\Framework\Discovery\Results\DiscoveryRegistry $registry ) { } public function getAttributeRegistry(): \App\Framework\Discovery\Results\AttributeRegistry { return $this->registry->attributes; } public function getDiscoveryRegistry(): \App\Framework\Discovery\Results\DiscoveryRegistry { return $this->registry; } }; $resolver = new DataProviderResolver($mockDiscovery); echo "✓ DataProviderResolver created\n\n"; // 3. Test: Initial Component Creation echo "3. Test: Initial Component Creation with dataSource='demo'...\n"; $component = new InfiniteScrollComponent( id: ComponentId::fromString('scroll:test'), dataProviderResolver: $resolver, items: [], currentPage: 0, pageSize: 5, dataSource: 'demo' ); echo "✓ Component created successfully\n"; $initialData = $component->getData(); echo " - Data has 'data_source': " . ($initialData->has('data_source') ? 'YES' : 'NO') . "\n"; echo " - dataSource value: '" . $initialData->get('data_source') . "'\n"; echo " - Items count: " . count($initialData->get('items')) . "\n\n"; // 4. Test: Execute Action echo "4. Test: Execute Action - loadMore()...\n"; try { $actionResult = $component->loadMore(); echo "✓ Action executed successfully\n"; echo " - Items loaded: " . count($actionResult->get('items')) . "\n"; echo " - Current page: " . $actionResult->get('current_page') . "\n"; echo " - Has 'data_source': " . ($actionResult->has('data_source') ? 'YES' : 'NO') . "\n"; echo " - dataSource value: '" . $actionResult->get('data_source') . "'\n\n"; } catch (\Exception $e) { echo "✗ FAILED: " . $e->getMessage() . "\n"; echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n"; echo " Stack trace:\n" . $e->getTraceAsString() . "\n\n"; exit(1); } // 5. Test: State Restoration echo "5. Test: State Restoration from ComponentData...\n"; echo " - Attempting to reconstruct component from action result...\n"; try { $restoredComponent = new InfiniteScrollComponent( id: ComponentId::fromString('scroll:test-restored'), dataProviderResolver: $resolver, initialData: $actionResult // This triggers state restoration path ); echo "✓ Component restored from ComponentData\n"; $restoredData = $restoredComponent->getData(); echo " - Restored items count: " . count($restoredData->get('items')) . "\n"; echo " - Restored page: " . $restoredData->get('current_page') . "\n"; echo " - Restored dataSource: '" . $restoredData->get('data_source') . "'\n\n"; } catch (\Exception $e) { echo "✗ FAILED: " . $e->getMessage() . "\n"; echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n"; echo " Stack trace:\n" . $e->getTraceAsString() . "\n\n"; exit(1); } // 6. Test: Action on Restored Component echo "6. Test: Action on Restored Component...\n"; try { $secondActionResult = $restoredComponent->loadMore(); echo "✓ Second action executed successfully\n"; echo " - Total items: " . count($secondActionResult->get('items')) . "\n"; echo " - Current page: " . $secondActionResult->get('current_page') . "\n"; echo " - dataSource: '" . $secondActionResult->get('data_source') . "'\n\n"; } catch (\Exception $e) { echo "✗ FAILED: " . $e->getMessage() . "\n"; echo " File: " . $e->getFile() . ":" . $e->getLine() . "\n"; exit(1); } // 7. Verify All Requirements echo "7. Verification of Requirements...\n"; $allPassed = true; // Requirement 1: dataSource preserved through state transformations if ($secondActionResult->get('data_source') !== 'demo') { echo "✗ FAIL: dataSource not preserved\n"; echo " Expected: 'demo'\n"; echo " Got: '" . $secondActionResult->get('data_source') . "'\n"; $allPassed = false; } else { echo "✓ PASS: dataSource preserved correctly ('demo')\n"; } // Requirement 2: Component state preserved correctly if ($secondActionResult->get('current_page') !== 2) { echo "✗ FAIL: Page progression incorrect\n"; echo " Expected page: 2\n"; echo " Got page: " . $secondActionResult->get('current_page') . "\n"; $allPassed = false; } else { echo "✓ PASS: Page progression correct (2)\n"; } // Requirement 3: Data accumulated correctly $expectedItems = 10; // 5 items per page * 2 pages $actualItems = count($secondActionResult->get('items')); if ($actualItems !== $expectedItems) { echo "✗ FAIL: Item accumulation incorrect\n"; echo " Expected items: $expectedItems\n"; echo " Got items: $actualItems\n"; $allPassed = false; } else { echo "✓ PASS: Item accumulation correct ($expectedItems items)\n"; } echo "\n" . str_repeat('=', 70) . "\n"; if ($allPassed) { echo "✅ ALL TESTS PASSED\n"; echo "DataProvider resolution flow is working correctly!\n"; echo "\n"; echo "Summary:\n"; echo "- Initial render with dataSource ✓\n"; echo "- Action execution with state update ✓\n"; echo "- State restoration from ComponentData ✓\n"; echo "- Provider resolution in restored component ✓\n"; echo "- Subsequent actions on restored component ✓\n"; exit(0); } else { echo "❌ SOME TESTS FAILED\n"; echo "Review failures above for details.\n"; exit(1); }