- 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)
219 lines
7.8 KiB
PHP
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";
|
|
} |