| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- <?php
- namespace SixShop\MakerBundle\Tests\Unit\Generator;
- use PHPUnit\Framework\TestCase;
- use SixShop\MakerBundle\Generator\ComposerGenerator;
- use Symfony\Component\Console\Style\SymfonyStyle;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Output\OutputInterface;
- class ComposerGeneratorTest extends TestCase
- {
- private $composerGenerator;
- private $io;
- private $testDir;
- protected function setUp(): void
- {
- $this->testDir = sys_get_temp_dir() . '/composer_test_' . uniqid();
- mkdir($this->testDir, 0777, true);
-
- // Create mock SymfonyStyle
- $this->io = $this->createMock(SymfonyStyle::class);
-
- $this->composerGenerator = new ComposerGenerator();
- }
- protected function tearDown(): void
- {
- if (is_dir($this->testDir)) {
- $this->removeDirectory($this->testDir);
- }
- }
- private function removeDirectory($dir)
- {
- if (!is_dir($dir)) {
- return;
- }
-
- $items = scandir($dir);
- foreach ($items as $item) {
- if ($item != '.' && $item != '..') {
- $path = $dir . DIRECTORY_SEPARATOR . $item;
- if (is_dir($path)) {
- $this->removeDirectory($path);
- } else {
- unlink($path);
- }
- }
- }
- rmdir($dir);
- }
- public function testGenerateContent()
- {
- $packageName = 'six-shop/test-extension';
- $namespace = 'SixShop\\TestExtension\\';
- $id = 'six-shop-test-extension';
- $description = 'A test extension package';
- $content = $this->composerGenerator->generateContent($packageName, $namespace, $id, $description);
- $this->assertIsString($content);
- $this->assertNotEmpty($content);
-
- // Test JSON structure
- $jsonData = json_decode($content, true);
- $this->assertIsArray($jsonData);
- $this->assertEquals(JSON_ERROR_NONE, json_last_error());
-
- // Test package information
- $this->assertEquals($packageName, $jsonData['name']);
- $this->assertEquals($description, $jsonData['description']);
-
- // Test PSR-4 autoloading
- $this->assertArrayHasKey('autoload', $jsonData);
- $this->assertArrayHasKey('psr-4', $jsonData['autoload']);
- $this->assertArrayHasKey($namespace, $jsonData['autoload']['psr-4']);
- $this->assertEquals('src', $jsonData['autoload']['psr-4'][$namespace]);
-
- // Test SixShop extension configuration
- $this->assertArrayHasKey('extra', $jsonData);
- $this->assertArrayHasKey('sixshop', $jsonData['extra']);
- $this->assertEquals($id, $jsonData['extra']['sixshop']['id']);
- }
- public function testSaveComposerFile()
- {
- $packageName = 'six-shop/test-extension';
- $content = '{"name": "six-shop/test-extension", "description": "Test"}';
-
- $this->io->expects($this->once())
- ->method('success')
- ->with($this->stringContains('composer.json 文件已成功生成'));
- $result = $this->composerGenerator->saveComposerFile($packageName, $content, $this->testDir, $this->io);
- $this->assertTrue($result);
- $this->assertFileExists($this->testDir . '/composer.json');
- $this->assertEquals($content, file_get_contents($this->testDir . '/composer.json'));
- }
- public function testSaveComposerFileFailure()
- {
- $packageName = 'six-shop/test-extension';
- $content = '{"name": "six-shop/test-extension"}';
- $invalidDir = '/invalid/directory/path';
-
- $this->io->expects($this->once())
- ->method('error')
- ->with($this->stringContains('无法创建目录'));
- $result = $this->composerGenerator->saveComposerFile($packageName, $content, $invalidDir, $this->io);
- $this->assertFalse($result);
- }
- public function testCreateComposerJson()
- {
- $packageName = 'six-shop/test-extension';
- $namespace = 'SixShop\\TestExtension\\';
- $id = 'six-shop-test-extension';
- $description = 'A test extension package';
- $this->io->expects($this->once())
- ->method('section')
- ->with('生成的 composer.json 内容:');
-
- $this->io->expects($this->once())
- ->method('text')
- ->with($this->isType('string'));
-
- $this->io->expects($this->once())
- ->method('confirm')
- ->with('是否将内容保存到 composer.json 文件?', true)
- ->willReturn(true);
-
- $this->io->expects($this->once())
- ->method('success')
- ->with($this->stringContains('composer.json 文件已成功生成'));
- $result = $this->composerGenerator->createComposerJson(
- $packageName, $namespace, $id, $description, $this->testDir, $this->io
- );
- $this->assertTrue($result);
- $this->assertFileExists($this->testDir . '/composer.json');
- }
- public function testCreateComposerJsonWithUserDecline()
- {
- $packageName = 'six-shop/test-extension';
- $namespace = 'SixShop\\TestExtension\\';
- $id = 'six-shop-test-extension';
- $description = 'A test extension package';
- $this->io->expects($this->once())
- ->method('confirm')
- ->with('是否将内容保存到 composer.json 文件?', true)
- ->willReturn(false);
- $result = $this->composerGenerator->createComposerJson(
- $packageName, $namespace, $id, $description, $this->testDir, $this->io
- );
- $this->assertTrue($result);
- $this->assertFileDoesNotExist($this->testDir . '/composer.json');
- }
- public function testGenerateContentWithDifferentNamespaces()
- {
- $testCases = [
- ['SixShop\\Hello\\', 'six-shop/hello'],
- ['MyCompany\\Extensions\\TestExt\\', 'mycompany/test-extension'],
- ['SingleNamespace\\', 'vendor/package']
- ];
- foreach ($testCases as [$namespace, $packageName]) {
- $content = $this->composerGenerator->generateContent($packageName, $namespace, 'test-id', 'Test description');
-
- $jsonData = json_decode($content, true);
- $this->assertArrayHasKey($namespace, $jsonData['autoload']['psr-4']);
- $this->assertEquals('src', $jsonData['autoload']['psr-4'][$namespace]);
- }
- }
- public function testJsonStructureCompliance()
- {
- $content = $this->composerGenerator->generateContent(
- 'six-shop/test-extension',
- 'SixShop\\TestExtension\\',
- 'test-extension-id',
- 'Test description'
- );
- $jsonData = json_decode($content, true);
-
- // Test required composer.json fields
- $this->assertArrayHasKey('name', $jsonData);
- $this->assertArrayHasKey('description', $jsonData);
- $this->assertArrayHasKey('type', $jsonData);
- $this->assertArrayHasKey('require', $jsonData);
- $this->assertArrayHasKey('autoload', $jsonData);
- $this->assertArrayHasKey('extra', $jsonData);
-
- // Test type field
- $this->assertEquals('sixshop-extension', $jsonData['type']);
-
- // Test minimum requirements
- $this->assertArrayHasKey('php', $jsonData['require']);
- $this->assertEquals('>=8.3', $jsonData['require']['php']);
- }
- public function testExtensionIdFormat()
- {
- $testCases = [
- 'six-shop/hello' => 'six-shop-hello',
- 'vendor/my-extension' => 'vendor-my-extension',
- 'company/test_pkg' => 'company-test_pkg'
- ];
- foreach ($testCases as $packageName => $expectedId) {
- $content = $this->composerGenerator->generateContent(
- $packageName,
- 'Test\\Namespace\\',
- $expectedId,
- 'Test description'
- );
-
- $jsonData = json_decode($content, true);
- $this->assertEquals($expectedId, $jsonData['extra']['sixshop']['id']);
- }
- }
- public function testGenerateContentErrorHandling()
- {
- // Test that the method works with valid parameters
- // Since the template exists, this should not throw an exception
- $content = $this->composerGenerator->generateContent(
- 'test/package',
- 'Test\\Namespace\\',
- 'test-id',
- 'Test description'
- );
-
- $this->assertIsString($content);
- $this->assertNotEmpty($content);
- }
- public function testSaveComposerFileDirectoryCreation()
- {
- $nestedDir = $this->testDir . '/nested/deep/directory';
- $packageName = 'six-shop/test-extension';
- $content = '{"name": "six-shop/test-extension"}';
-
- $this->io->expects($this->once())
- ->method('success');
- $result = $this->composerGenerator->saveComposerFile($packageName, $content, $nestedDir, $this->io);
- $this->assertTrue($result);
- $this->assertDirectoryExists($nestedDir);
- $this->assertFileExists($nestedDir . '/composer.json');
- }
- public function testCompletePackageJsonStructure()
- {
- $content = $this->composerGenerator->generateContent(
- 'six-shop/advanced-extension',
- 'SixShop\\AdvancedExtension\\',
- 'six-shop-advanced-extension',
- 'An advanced SixShop extension with comprehensive features'
- );
- $jsonData = json_decode($content, true);
-
- // Verify complete structure
- $expectedStructure = [
- 'name' => 'six-shop/advanced-extension',
- 'description' => 'An advanced SixShop extension with comprehensive features',
- 'type' => 'sixshop-extension',
- 'require' => [
- 'php' => '>=8.3',
- 'six-shop/core' => '>=0.6 <1.0'
- ],
- 'autoload' => [
- 'psr-4' => [
- 'SixShop\\AdvancedExtension\\' => 'src'
- ]
- ],
- 'extra' => [
- 'sixshop' => [
- 'id' => 'six-shop-advanced-extension',
- 'class' => 'SixShop\\AdvancedExtension\\Extension'
- ]
- ]
- ];
- $this->assertEquals($expectedStructure['name'], $jsonData['name']);
- $this->assertEquals($expectedStructure['description'], $jsonData['description']);
- $this->assertEquals($expectedStructure['type'], $jsonData['type']);
- $this->assertEquals($expectedStructure['require'], $jsonData['require']);
- $this->assertEquals($expectedStructure['autoload'], $jsonData['autoload']);
- $this->assertEquals($expectedStructure['extra'], $jsonData['extra']);
- }
- }
|