Files
Gnuboard7/tests/Unit/Extension/GeneratesComponentManifestNewlineTest.php
T
HeuJung 151a7ae945 fix(extensions,core): 저장 대상이 아닌 편집기가 폼을 변경됨으로 만들지 않게
미리보기 편집기는 설정을 시험해 보는 자리인데, 본문 동기화가 hasChanges 를
렌더를 일으키는 setLocal 로 올리면서 시험 입력만으로 [저장] 이 켜졌다.
어느 편집기가 저장 대상인지는 레이아웃만 알므로 핸들러가 필드명을 알아보게
하지 않고 trackChanges 선언으로 받는다 — 하드코딩하면 다른 확장이 같은
미리보기 패턴을 쓸 때 그대로 재발한다.

같은 결함이 형제 경로에도 있었다. 평문 폴백은 hasChanges 를 본문 배치
(render:false + selfManaged:true)에 실어, 편집기 자산을 못 불러온 환경에서
본문만 고치면 저장 버튼이 잠긴 채로 남았다 — 폐쇄망에서는 그 폴백이 정상
경로다. 폴백은 렌더 시점에도 같은 함수를 부르므로 화면을 여는 것만으로
변경됨이 되지 않도록, 사용자 입력에서 온 호출만 플래그를 올린다.

components.json 생성기는 종결 개행을 PHP_EOL 로 써서 Windows 빌드마다
그 파일을 유령 변경으로 남겼다. 줄 내용이 같아 diff 가 비어 보이므로
무엇이 바뀐 것인지 알 수 없는 변경만 쌓인다.
2026-09-01 21:53:47 +09:00

106 lines
3.4 KiB
PHP

<?php
namespace Tests\Unit\Extension;
use App\Extension\Traits\GeneratesComponentManifest;
use Tests\TestCase;
/**
* components.json 종결 개행이 빌드 OS 에 좌우되지 않는지 확인합니다.
*
* 이 매니페스트는 `module:build` / `plugin:build` 산출물이면서 Git 추적 대상이다.
* 종결 개행을 PHP_EOL 로 쓰면 Windows 빌드에서만 "\r\n" 이 되어, 소스를 하나도
* 고치지 않고 다시 빌드하기만 해도 변경으로 잡힌다. 줄 내용은 같으므로 diff 는
* 비어 보이고, 무엇이 바뀐 것인지 알 수 없는 변경만 남는다.
*/
class GeneratesComponentManifestNewlineTest extends TestCase
{
private string $buildPath;
protected function setUp(): void
{
parent::setUp();
$this->buildPath = sys_get_temp_dir().'/g7-cm-'.uniqid();
mkdir($this->buildPath.'/resources/js/components/basic', 0o777, true);
file_put_contents($this->buildPath.'/plugin.json', json_encode(['version' => '1.2.3']));
file_put_contents($this->buildPath.'/resources/js/components/basic/Foo.tsx', 'export const Foo = () => null;');
}
protected function tearDown(): void
{
$this->removeDirectory($this->buildPath);
parent::tearDown();
}
/**
* 트레이트를 쓰는 익명 클래스로 생성기를 호출합니다.
*
* @return array{written: bool, count: int, path: string} 작성 결과
*/
private function generate(): array
{
$generator = new class
{
use GeneratesComponentManifest;
/**
* protected 생성기를 테스트에서 호출하기 위한 통로입니다.
*
* @param string $buildPath 빌드 경로
* @return array{written: bool, count: int, path: string} 작성 결과
*/
public function run(string $buildPath): array
{
return $this->generateComponentManifest($buildPath, 'sirsoft-sample');
}
};
return $generator->run($this->buildPath);
}
/**
* 디렉토리를 재귀 삭제합니다.
*
* @param string $dir 삭제할 디렉토리
* @return void
*/
private function removeDirectory(string $dir): void
{
if (! is_dir($dir)) {
return;
}
foreach (scandir($dir) ?: [] as $entry) {
if ($entry === '.' || $entry === '..') {
continue;
}
$path = $dir.'/'.$entry;
is_dir($path) ? $this->removeDirectory($path) : @unlink($path);
}
@rmdir($dir);
}
public function test_manifest_ends_with_lf_not_platform_eol(): void
{
$result = $this->generate();
$this->assertTrue($result['written']);
$raw = file_get_contents($result['path']);
$this->assertStringEndsWith("}\n", $raw, 'LF 로 끝나야 한다');
$this->assertStringNotContainsString("\r", $raw, '어느 줄에도 CR 이 없어야 한다 — 있으면 Windows 빌드에서만 변경으로 잡힌다');
}
public function test_rebuilding_the_same_source_produces_identical_bytes(): void
{
$first = file_get_contents($this->generate()['path']);
$second = file_get_contents($this->generate()['path']);
$this->assertSame($first, $second, '같은 소스를 다시 빌드하면 바이트까지 같아야 한다');
}
}