feat: establish catalog identity and atomic file ownership

This commit is contained in:
Cline committed 2026-10-12 19:38:38 -05:00
1 parent 390a7a557a
commit 6b9fb54b4f
16 files changed
+1381 -23

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace MeshVault\Tests\Unit\Catalog;
use InvalidArgumentException;
use MeshVault\Catalog\ManagedPath;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
final class ManagedPathTest extends TestCase
{
#[DataProvider('validPaths')]
public function testPreservesCanonicalSpelling(string $path): void
{
self::assertSame($path, ManagedPath::validate($path));
}
public static function validPaths(): array
{
return [['part.stl'], ['Folder/模型 A.STL'], ['a/.hidden'], ['a/space inside.stl']];
}
#[DataProvider('invalidPaths')]
public function testRejectsAliases(string $path): void
{
$this->expectException(InvalidArgumentException::class);
ManagedPath::validate($path);
}
public static function invalidPaths(): array
{
return array_map(static fn (string $path): array => [$path], [
'', '/a', '//server/a', 'C:/a', 'C:a', 'a\\b', "a\0b", 'https://host/a',
'file:a', 'a//b', 'a/', '.', '..', './a', 'a/../b', 'a/./b',
]);
}
public function testPlatformSpecificRestrictions(): void
{
foreach (['a/b.', 'a/b ', 'a/b:c'] as $path) {
if (PHP_OS_FAMILY === 'Windows') {
try {
ManagedPath::validate($path);
self::fail('Expected Windows alias rejection');
} catch (InvalidArgumentException) {
self::assertTrue(true);
}
} else {
self::assertSame($path, ManagedPath::validate($path));
}
}
}
}