Files
breadcrumb-the-shire/tests/Architecture/PageTemplateNamingTest.php

87 lines
3.2 KiB
PHP
Raw Normal View History

<?php
namespace MintyPHP\Tests\Architecture;
use PHPUnit\Framework\TestCase;
/**
* MintyPHP's Router parses page filenames by splitting on parentheses. URL
* parameters belong ONLY in the `.php` action filename (e.g. `view($id).php`);
* the `.phtml` view filename must contain exactly ONE paren group for the
* template name (`view(default).phtml` or `view(none).phtml`).
*
* Nested paren groups like `view($id)(none).phtml` cause the router's regex
* split to produce an empty view name the file silently resolves to the
* wrong path and the response is an empty body with no visible error.
*
* Reference: vendor/mintyphp/core/src/Router.php::extractParts()
*/
class PageTemplateNamingTest extends TestCase
{
use ProjectFileAssertionSupport;
public function testPhtmlFilenamesHaveExactlyOneParenGroup(): void
{
$root = $this->projectRootPath();
$scanRoots = [$root . '/pages'];
$modulesDir = $root . '/modules';
if (is_dir($modulesDir)) {
foreach (scandir($modulesDir) ?: [] as $moduleEntry) {
if ($moduleEntry === '.' || $moduleEntry === '..') {
continue;
}
$modulePages = $modulesDir . '/' . $moduleEntry . '/pages';
if (is_dir($modulePages)) {
$scanRoots[] = $modulePages;
}
}
}
$violations = [];
foreach ($scanRoots as $scanRoot) {
if (!is_dir($scanRoot)) {
continue;
}
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scanRoot, \FilesystemIterator::SKIP_DOTS));
/** @var \SplFileInfo $file */
foreach ($iterator as $file) {
if (!$file->isFile() || $file->getExtension() !== 'phtml') {
continue;
}
$name = $file->getFilename();
$openCount = substr_count($name, '(');
$closeCount = substr_count($name, ')');
$relativePath = str_replace($root . '/', '', $file->getPathname());
if ($openCount !== $closeCount) {
$violations[] = sprintf('%s — mismatched parens', $relativePath);
continue;
}
// Partials (`_form.phtml`, shared includes) have zero paren groups — skip them.
if ($openCount === 0) {
continue;
}
// Routed views must have exactly one paren group: `<view>(<template>).phtml`.
if ($openCount !== 1) {
$violations[] = sprintf(
'%s — found %d paren groups, expected exactly 1 (template only). '
. 'URL parameters belong in the .php action filename, not the .phtml view. '
. "Nested paren groups break MintyPHP's Router silently (empty response).",
$relativePath,
$openCount
);
}
}
}
$this->assertSame(
[],
$violations,
".phtml filename convention violations:\n" . implode("\n", $violations)
);
}
}