Skip to content

Commit c0f8bf3

Browse files
committed
test(config): add KcodeComposerGeneratorTest + lean build-phar.php
KcodeComposerGeneratorTest (5 cases): toolName, outputPath, default versions, user version overrides, config section, output newline. bin/build-phar.php: restored to lean build strategy — bundles only src/ and an inline PSR-4 autoloader. Tools install dynamically via kcode init, avoiding prohibitively slow Phar::compressFiles(GZ) on large vendor trees (documented pitfall #12 in devkit KI).
1 parent a9f83f6 commit c0f8bf3

2 files changed

Lines changed: 139 additions & 3 deletions

File tree

bin/build-phar.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
<?php
2+
23
declare(strict_types=1);
34

45
/**
5-
* Manual PHAR builder for kcode — bypasses Box chdir() bug on PHP 8.4
6+
* Manual PHAR builder for kcode — bypasses Box chdir() bug on PHP 8.4.
7+
*
8+
* The PHAR is intentionally lean: it bundles only the KaririCode\Devkit
9+
* source classes and a minimal PSR-4 autoloader. Dev tools (phpunit,
10+
* phpstan, etc.) are NOT bundled — `kcode init` installs them dynamically
11+
* into .kcode/vendor/ of the target project via composer.
612
*/
713

8-
$root = dirname(__DIR__);
9-
$output = $root . '/build/kcode.phar';
14+
$root = dirname(__DIR__);
15+
$output = $root . '/build/kcode.phar';
1016

1117
if (file_exists($output)) {
1218
unlink($output);
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\Devkit\Tests\Unit\Configuration;
6+
7+
use KaririCode\Devkit\Configuration\KcodeComposerGenerator;
8+
use KaririCode\Devkit\Core\ProjectContext;
9+
use PHPUnit\Framework\Attributes\CoversClass;
10+
use PHPUnit\Framework\Attributes\Test;
11+
use PHPUnit\Framework\Attributes\UsesClass;
12+
use PHPUnit\Framework\TestCase;
13+
14+
#[CoversClass(KcodeComposerGenerator::class)]
15+
#[UsesClass(ProjectContext::class)]
16+
final class KcodeComposerGeneratorTest extends TestCase
17+
{
18+
private ProjectContext $context;
19+
20+
protected function setUp(): void
21+
{
22+
$this->context = new ProjectContext(
23+
projectRoot: '/tmp/test-project',
24+
projectName: 'test/project',
25+
namespace: 'Test\\Project',
26+
phpVersion: '8.4',
27+
phpstanLevel: 9,
28+
psalmLevel: 3,
29+
sourceDirs: ['/tmp/test-project/src'],
30+
testDirs: ['/tmp/test-project/tests'],
31+
excludeDirs: ['src/Contract'],
32+
testSuites: ['Unit' => 'tests/Unit'],
33+
coverageExclude: ['src/Exception'],
34+
csFixerRules: [],
35+
rectorSets: [],
36+
toolVersions: [],
37+
);
38+
}
39+
40+
#[Test]
41+
public function toolNameIsKcodeComposer(): void
42+
{
43+
$generator = new KcodeComposerGenerator();
44+
$this->assertSame('kcode-composer', $generator->toolName());
45+
}
46+
47+
#[Test]
48+
public function outputPathIsComposerJson(): void
49+
{
50+
$generator = new KcodeComposerGenerator();
51+
$this->assertSame('composer.json', $generator->outputPath());
52+
}
53+
54+
#[Test]
55+
public function generateProducesValidJsonWithDefaultVersions(): void
56+
{
57+
$generator = new KcodeComposerGenerator();
58+
$output = $generator->generate($this->context);
59+
60+
/** @var array<string, mixed> $manifest */
61+
$manifest = json_decode($output, true, 512, \JSON_THROW_ON_ERROR);
62+
63+
$this->assertSame('kariricode/devkit-tools', $manifest['name']);
64+
$this->assertIsArray($manifest['require']);
65+
66+
// All 5 default tools must be present
67+
$require = $manifest['require'];
68+
$this->assertArrayHasKey('phpunit/phpunit', $require);
69+
$this->assertArrayHasKey('phpstan/phpstan', $require);
70+
$this->assertArrayHasKey('friendsofphp/php-cs-fixer', $require);
71+
$this->assertArrayHasKey('rector/rector', $require);
72+
$this->assertArrayHasKey('vimeo/psalm', $require);
73+
}
74+
75+
#[Test]
76+
public function generateRespectsUserToolVersionOverrides(): void
77+
{
78+
$contextWithVersions = new ProjectContext(
79+
projectRoot: '/tmp/test-project',
80+
projectName: 'test/project',
81+
namespace: 'Test\\Project',
82+
phpVersion: '8.4',
83+
phpstanLevel: 9,
84+
psalmLevel: 3,
85+
sourceDirs: ['/tmp/test-project/src'],
86+
testDirs: ['/tmp/test-project/tests'],
87+
excludeDirs: [],
88+
testSuites: [],
89+
coverageExclude: [],
90+
csFixerRules: [],
91+
rectorSets: [],
92+
toolVersions: ['phpunit' => '^11.0', 'phpstan' => '^1.12'],
93+
);
94+
95+
$generator = new KcodeComposerGenerator();
96+
$output = $generator->generate($contextWithVersions);
97+
98+
/** @var array<string, mixed> $manifest */
99+
$manifest = json_decode($output, true, 512, \JSON_THROW_ON_ERROR);
100+
101+
$require = $manifest['require'];
102+
$this->assertSame('^11.0', $require['phpunit/phpunit']);
103+
$this->assertSame('^1.12', $require['phpstan/phpstan']);
104+
// Unoverridden tool still uses default
105+
$this->assertStringStartsWith('^', $require['rector/rector']);
106+
}
107+
108+
#[Test]
109+
public function generateIncludesComposerConfigSection(): void
110+
{
111+
$generator = new KcodeComposerGenerator();
112+
$output = $generator->generate($this->context);
113+
114+
/** @var array<string, mixed> $manifest */
115+
$manifest = json_decode($output, true, 512, \JSON_THROW_ON_ERROR);
116+
117+
$this->assertIsArray($manifest['config']);
118+
$this->assertSame('full', $manifest['config']['bin-compat']);
119+
$this->assertTrue($manifest['config']['optimize-autoloader']);
120+
}
121+
122+
#[Test]
123+
public function generateOutputEndsWithNewline(): void
124+
{
125+
$generator = new KcodeComposerGenerator();
126+
$output = $generator->generate($this->context);
127+
128+
$this->assertStringEndsWith(\PHP_EOL, $output);
129+
}
130+
}

0 commit comments

Comments
 (0)