New contracts enforce repository layer isolation, no HTML in services, no DB calls in views, module session key prefixes, and asset versioning. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
77 lines
2.1 KiB
PHP
77 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace MintyPHP\Tests\Architecture;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Views (.phtml) must be pure rendering — no database calls allowed.
|
|
* All data must be prepared in actions and passed via view variables.
|
|
*/
|
|
class ViewLayerNoDbCallsContractTest extends TestCase
|
|
{
|
|
use ProjectFileAssertionSupport;
|
|
|
|
/** @var list<string> */
|
|
private const DB_PATTERNS = [
|
|
'/->query\s*\(/',
|
|
'/->prepare\s*\(/',
|
|
'/->execute\s*\(/',
|
|
'/->fetch\s*\(/',
|
|
'/->fetchAll\s*\(/',
|
|
'/->fetchColumn\s*\(/',
|
|
'/\bnew\s+PDO\b/',
|
|
'/\$pdo\b/',
|
|
];
|
|
|
|
public function testCorePagesViewsContainNoDbCalls(): void
|
|
{
|
|
$this->assertNoDbCallsInViews('pages');
|
|
}
|
|
|
|
public function testModuleViewsContainNoDbCalls(): void
|
|
{
|
|
$root = $this->projectRootPath();
|
|
$modulesDir = $root . '/modules';
|
|
if (!is_dir($modulesDir)) {
|
|
self::markTestSkipped('modules/ directory missing.');
|
|
}
|
|
|
|
foreach (scandir($modulesDir) ?: [] as $entry) {
|
|
if ($entry === '.' || $entry === '..' || !is_dir($modulesDir . '/' . $entry)) {
|
|
continue;
|
|
}
|
|
$pagesRel = 'modules/' . $entry . '/pages';
|
|
if (is_dir($root . '/' . $pagesRel)) {
|
|
$this->assertNoDbCallsInViews($pagesRel);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testTemplatesContainNoDbCalls(): void
|
|
{
|
|
$this->assertNoDbCallsInViews('templates');
|
|
}
|
|
|
|
private function assertNoDbCallsInViews(string $relativeDirectory): void
|
|
{
|
|
$allViolations = [];
|
|
|
|
foreach (self::DB_PATTERNS as $pattern) {
|
|
$hits = $this->findPatternMatchesInFiles($relativeDirectory, $pattern, ['phtml']);
|
|
foreach ($hits as $file) {
|
|
$allViolations[$file] = true;
|
|
}
|
|
}
|
|
|
|
$violations = array_keys($allViolations);
|
|
sort($violations);
|
|
|
|
self::assertSame(
|
|
[],
|
|
$violations,
|
|
"Views must not contain database calls. Violations found:\n" . implode("\n", $violations)
|
|
);
|
|
}
|
|
}
|