testDir = sys_get_temp_dir() . '/sixshop_model_test_' . uniqid(); if (!is_dir($this->testDir)) { mkdir($this->testDir, 0755, true); } $this->generator = new ModelGenerator(); $this->extensionInfo = [ 'namespace' => 'SixShop\\Test\\', 'packageName' => 'sixshop/test', 'id' => 'sixshop-test' ]; // Create mock SymfonyStyle $input = new ArrayInput([]); $output = new BufferedOutput(); $this->io = new SymfonyStyle($input, $output); } protected function tearDown(): void { if (is_dir($this->testDir)) { $this->removeDirectory($this->testDir); } } private function removeDirectory(string $dir): void { if (is_dir($dir)) { $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir . DIRECTORY_SEPARATOR . $file; is_dir($path) ? $this->removeDirectory($path) : unlink($path); } rmdir($dir); } } public function testGenerateBasicModel(): void { $tableName = 'test_users'; $tableComment = 'Test users table'; $fields = [ ['name' => 'id', 'type' => 'biginteger'], ['name' => 'name', 'type' => 'string', 'length' => 100], ['name' => 'email', 'type' => 'string', 'length' => 255] ]; $result = $this->generator->generateModel( $tableName, $tableComment, $fields, $this->extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $modelFile = $this->testDir . '/src/Model/TestUsersModel.php'; $this->assertFileExists($modelFile); $content = file_get_contents($modelFile); $this->assertStringContainsString('class TestUsersModel extends Model', $content); $this->assertStringContainsString('protected function getOptions(): array', $content); $this->assertStringContainsString("'name' => 'test_users'", $content); } public function testModelWithComplexFields(): void { $tableName = 'products'; $tableComment = 'Products table'; $fields = [ ['name' => 'id', 'type' => 'biginteger'], ['name' => 'name', 'type' => 'string', 'length' => 200], ['name' => 'price', 'type' => 'decimal', 'precision' => 10, 'scale' => 2], ['name' => 'is_active', 'type' => 'boolean', 'default' => true], ['name' => 'config', 'type' => 'json'], ['name' => 'created_at', 'type' => 'timestamp'], ['name' => 'updated_at', 'type' => 'timestamp'] ]; $result = $this->generator->generateModel( $tableName, $tableComment, $fields, $this->extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $modelFile = $this->testDir . '/src/Model/ProductModel.php'; $this->assertFileExists($modelFile); $content = file_get_contents($modelFile); // Check field type mappings $this->assertStringContainsString("'name' => 'string'", $content); $this->assertStringContainsString("'price' => 'float'", $content); $this->assertStringContainsString("'is_active' => 'boolean'", $content); $this->assertStringContainsString("'config' => 'json'", $content); // Check timestamp configuration $this->assertStringContainsString("'auto_timestamp' => true", $content); $this->assertStringContainsString("'create_time' => 'create_time'", $content); $this->assertStringContainsString("'update_time' => 'update_time'", $content); } public function testModelNamespaceGeneration(): void { $tableName = 'orders'; $fields = [['name' => 'id', 'type' => 'biginteger']]; $customExtensionInfo = [ 'namespace' => 'MyVendor\\CustomPackage\\', 'packageName' => 'myvendor/custom-package', 'id' => 'myvendor-custom-package' ]; $result = $this->generator->generateModel( $tableName, 'Orders table', $fields, $customExtensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $modelFile = $this->testDir . '/src/Model/OrderModel.php'; $this->assertFileExists($modelFile); $content = file_get_contents($modelFile); $this->assertStringContainsString('namespace MyVendor\\CustomPackage\\Model;', $content); $this->assertStringContainsString('class OrderModel extends Model', $content); } public function testModelWithTimestampFieldNaming(): void { $tableName = 'logs'; $fields = [ ['name' => 'id', 'type' => 'biginteger'], ['name' => 'message', 'type' => 'text'], ['name' => 'created_at', 'type' => 'timestamp'], ['name' => 'updated_at', 'type' => 'timestamp'], ['name' => 'deleted_at', 'type' => 'timestamp'] ]; $result = $this->generator->generateModel( $tableName, 'Logs table', $fields, $this->extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $modelFile = $this->testDir . '/src/Model/LogModel.php'; $content = file_get_contents($modelFile); // Check that timestamp fields are mapped to '_time' suffix $this->assertStringContainsString("'create_time' => 'create_time'", $content); $this->assertStringContainsString("'update_time' => 'update_time'", $content); $this->assertStringContainsString("'delete_time' => 'delete_time'", $content); } public function testModelDirectoryCreation(): void { $tableName = 'categories'; $fields = [['name' => 'id', 'type' => 'biginteger']]; // Use a path that doesn't exist $newTestDir = $this->testDir . '/nonexistent/path'; $result = $this->generator->generateModel( $tableName, 'Categories table', $fields, $this->extensionInfo, $newTestDir, $this->io ); $this->assertTrue($result); $modelFile = $newTestDir . '/src/Model/CategoryModel.php'; $this->assertFileExists($modelFile); // Check that directories were created $this->assertTrue(is_dir($newTestDir . '/src/Model')); } public function testModelValidationRules(): void { $tableName = 'users'; $fields = [ ['name' => 'id', 'type' => 'biginteger'], ['name' => 'username', 'type' => 'string', 'length' => 50, 'null' => false], ['name' => 'email', 'type' => 'string', 'length' => 255, 'null' => false], ['name' => 'age', 'type' => 'integer', 'null' => true] ]; $result = $this->generator->generateModel( $tableName, 'Users table', $fields, $this->extensionInfo, $this->testDir, $this->io ); $this->assertTrue($result); $modelFile = $this->testDir . '/src/Model/UserModel.php'; $content = file_get_contents($modelFile); // Check validation rules are generated $this->assertStringContainsString("'validate' => [", $content); $this->assertStringContainsString("'username' => 'require|max:50'", $content); $this->assertStringContainsString("'email' => 'require|email|max:255'", $content); } }