Files
michaelschiemer/scripts/debug/debug_tui_navigation_logic.php
Michael Schiemer 887847dde6 refactor: reorganize project structure for better maintainability
- Move 45 debug/test files from root to organized scripts/ directories
- Secure public/ directory by removing debug files (security improvement)
- Create structured scripts organization:
  • scripts/debug/      (20 files) - Framework debugging tools
  • scripts/test/       (18 files) - Test and validation scripts
  • scripts/maintenance/ (5 files) - Maintenance utilities
  • scripts/dev/         (2 files) - Development tools

Security improvements:
- Removed all debug/test files from public/ directory
- Only production files remain: index.php, health.php

Root directory cleanup:
- Reduced from 47 to 2 PHP files in root
- Only essential production files: console.php, worker.php

This improves:
 Security (no debug code in public/)
 Organization (clear separation of concerns)
 Maintainability (easy to find and manage scripts)
 Professional structure (clean root directory)
2025-10-05 10:59:15 +02:00

219 lines
7.8 KiB
PHP

<?php
require_once __DIR__ . '/vendor/autoload.php';
// Debug TUI navigation logic specifically
use App\Framework\Console\Components\TuiState;
use App\Framework\Console\Components\TuiInputHandler;
use App\Framework\Console\Components\TuiCommandExecutor;
use App\Framework\Console\CommandHistory;
use App\Framework\Console\CommandGroupRegistry;
use App\Framework\Console\TuiView;
use App\Framework\Console\TuiKeyCode;
use App\Framework\Discovery\Results\DiscoveryRegistry;
echo "Debug TUI Navigation Logic\n";
echo "==========================\n\n";
try {
// Create discovery registry that returns real-looking data
$discoveryRegistry = new class implements DiscoveryRegistry {
public function interfaces() {
return new class {
public function get(string $interface) { return []; }
};
}
public function attributes() {
return new class {
public function get(string $attributeClass) { return []; }
};
}
};
// Create mock executor with debug output
$mockExecutor = new class implements TuiCommandExecutor {
public function executeSelectedCommand(object $command): void {
echo "\n🚀 Mock: Execute command\n";
}
public function executeCommand(string $commandName): void {
echo "\n🚀 Mock: Execute command: $commandName\n";
}
public function validateSelectedCommand(object $command): void {
echo "\n✓ Mock: Validate command\n";
}
public function validateCommand(string $commandName): void {
echo "\n✓ Mock: Validate command: $commandName\n";
}
public function showSelectedCommandHelp(object $command): void {
echo "\n📚 Mock: Show help\n";
}
public function showCommandHelp(string $commandName): void {
echo "\n📚 Mock: Show help: $commandName\n";
}
public function showAllCommandsHelp(): void {
echo "\n📚 Mock: Show all commands help\n";
}
public function startInteractiveForm(object $command, \App\Framework\Console\Components\TuiState $state): void {
echo "\n📝 Mock: Start form\n";
}
public function findCommandObject(string $commandName): ?object {
return null;
}
};
// Create components
$state = new TuiState();
$history = new CommandHistory();
$inputHandler = new TuiInputHandler($mockExecutor);
$groupRegistry = new CommandGroupRegistry($discoveryRegistry);
echo "✓ Components created\n";
// Since discovery is empty, let's manually create categories like the real TUI
$testCategories = [
[
'name' => 'Testing',
'description' => 'Test commands',
'icon' => '🧪',
'priority' => 0,
'commands' => []
],
[
'name' => 'Demo',
'description' => 'Demo commands',
'icon' => '🎮',
'priority' => 0,
'commands' => []
],
[
'name' => 'Generator',
'description' => 'Code generation',
'icon' => '⚙️',
'priority' => 0,
'commands' => []
],
[
'name' => 'General',
'description' => 'General commands',
'icon' => '📂',
'priority' => 0,
'commands' => []
]
];
echo "📊 Test Categories:\n";
foreach ($testCategories as $index => $category) {
echo " [$index] {$category['icon']} {$category['name']} - {$category['description']}\n";
}
echo "\n";
// Setup TUI state
$state->setCategories($testCategories);
$state->setCurrentView(TuiView::CATEGORIES);
$state->setRunning(true);
echo "✓ TUI State initialized:\n";
echo " Categories: " . count($testCategories) . "\n";
echo " Current View: " . $state->getCurrentView()->name . "\n";
echo " Selected Category: " . $state->getSelectedCategory() . "\n";
$currentCategory = $state->getCurrentCategory();
if ($currentCategory) {
echo " Current Category: '{$currentCategory['name']}'\n";
} else {
echo " ❌ ERROR: getCurrentCategory() returned NULL!\n";
echo " This would cause navigation to fail!\n";
}
echo "\n=== STEP-BY-STEP NAVIGATION DEBUG ===\n\n";
function debugState($state, $step) {
echo "Step $step State:\n";
echo " - Selected Index: " . $state->getSelectedCategory() . "\n";
echo " - Current View: " . $state->getCurrentView()->name . "\n";
$category = $state->getCurrentCategory();
if ($category) {
echo " - Current Category: '{$category['name']}'\n";
} else {
echo " - ❌ Current Category: NULL\n";
}
echo "\n";
}
// Initial state
debugState($state, "Initial");
// Test 1: Direct TuiState navigation
echo "🔍 Test 1: Direct TuiState navigation\n";
echo "Calling \$state->navigateDown()...\n";
$state->navigateDown();
debugState($state, "After navigateDown()");
echo "Calling \$state->navigateUp()...\n";
$state->navigateUp();
debugState($state, "After navigateUp()");
// Test 2: TuiInputHandler navigation
echo "🔍 Test 2: TuiInputHandler with Arrow Keys\n";
echo "Simulating ARROW_DOWN input...\n";
echo "Key code: '" . TuiKeyCode::ARROW_DOWN->value . "' (hex: " . bin2hex(TuiKeyCode::ARROW_DOWN->value) . ")\n";
$beforeIndex = $state->getSelectedCategory();
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
$afterIndex = $state->getSelectedCategory();
echo "Before: $beforeIndex, After: $afterIndex\n";
echo "Changed: " . ($beforeIndex !== $afterIndex ? "YES ✓" : "NO ❌") . "\n";
debugState($state, "After ARROW_DOWN");
echo "Simulating ARROW_UP input...\n";
echo "Key code: '" . TuiKeyCode::ARROW_UP->value . "' (hex: " . bin2hex(TuiKeyCode::ARROW_UP->value) . ")\n";
$beforeIndex = $state->getSelectedCategory();
$inputHandler->handleInput(TuiKeyCode::ARROW_UP->value, $state, $history);
$afterIndex = $state->getSelectedCategory();
echo "Before: $beforeIndex, After: $afterIndex\n";
echo "Changed: " . ($beforeIndex !== $afterIndex ? "YES ✓" : "NO ❌") . "\n";
debugState($state, "After ARROW_UP");
// Test 3: Check bounds
echo "🔍 Test 3: Boundary testing\n";
// Go to last category
$lastIndex = count($testCategories) - 1;
$state->setSelectedCategory($lastIndex);
echo "Set to last category ($lastIndex)\n";
debugState($state, "Set to last");
echo "Try to go beyond last (ARROW_DOWN)...\n";
$beforeIndex = $state->getSelectedCategory();
$inputHandler->handleInput(TuiKeyCode::ARROW_DOWN->value, $state, $history);
$afterIndex = $state->getSelectedCategory();
echo "Before: $beforeIndex, After: $afterIndex\n";
echo "Boundary protected: " . ($beforeIndex === $afterIndex ? "YES ✓" : "NO ❌") . "\n";
// Test 4: Check TuiInputHandler logic
echo "\n🔍 Test 4: Debug TuiInputHandler logic\n";
// Let's trace what happens in handleInput
echo "Current view check: " . $state->getCurrentView()->name . "\n";
echo "Is CATEGORIES view: " . ($state->getCurrentView() === TuiView::CATEGORIES ? "YES" : "NO") . "\n";
if ($state->getCurrentView() === TuiView::CATEGORIES) {
echo "✓ View is correct for category navigation\n";
} else {
echo "❌ View is not CATEGORIES - navigation won't work!\n";
}
echo "\n✅ NAVIGATION DEBUG COMPLETED\n";
} catch (\Throwable $e) {
echo "\n❌ DEBUG FAILED:\n";
echo "Error: " . $e->getMessage() . "\n";
echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n";
echo "\nStack trace:\n" . $e->getTraceAsString() . "\n";
}