wurzel = dirname(__DIR__); $this->seitenrahmenBindetRechnerEin(); $this->stilblattZeigtSymbol(); $this->skriptRechnetOhneEval(); $this->genaueFelderTragenNachkommastellen(); } private function seitenrahmenBindetRechnerEin(): void { $kopf = $this->lies('src/Views/layout/kopf.php'); $this->assert( str_contains($kopf, ''), 'Der Seitenrahmen bindet rechner.js ein' ); $this->assert( strpos($kopf, '/static/betrag.js') !== false && strpos($kopf, '/static/betrag.js') < strpos($kopf, '/static/rechner.js'), 'betrag.js steht vor rechner.js – der Rechner liest den Feldwert damit' ); $this->assert(is_file($this->wurzel . '/public/static/rechner.js'), 'rechner.js liegt unter public/static'); } private function stilblattZeigtSymbol(): void { $css = $this->lies('public/static/app.css'); $this->assert( (bool)preg_match( '/input\[type="text"\]\[inputmode="decimal"\]:not\(\[data-ohne-rechner\]\)[^{]*\{[^}]*padding-right:[^}]*background-image:\s*url\("data:image\/svg\+xml/', $css ), 'Zahlenfelder tragen rechts das Rechnersymbol und halten den Platz dafür frei' ); $this->assert( (bool)preg_match('/\.rechner-tasten\s*\{[^}]*grid-template-columns:\s*repeat\(4, 1fr\)/', $css), 'Das Tastenfeld steht in vier Spalten' ); $this->assert( !preg_match('/\.rechner[^{]*\{[^}]*#[0-9a-f]{3,6}\b/i', $css), 'Der Rechner nimmt seine Farben aus den Custom Properties des Themas' ); } private function skriptRechnetOhneEval(): void { $js = $this->lies('public/static/rechner.js'); $this->assert(!preg_match('/\beval\s*\(|new Function\s*\(/', $js), 'Gerechnet wird ohne eval'); $this->assert(str_contains($js, "'input[type=\"text\"][inputmode=\"decimal\"]"), 'Der Rechner hängt an allen Zahlenfeldern'); foreach (["'Enter'", "'Escape'", "'C'", "'='"] as $taste) { $this->assert(str_contains($js, $taste), "Taste $taste ist belegt"); } } private function genaueFelderTragenNachkommastellen(): void { $felder = [ 'src/Views/wertpapiere/formular.php' => ['stueck' => 6, 'kurs' => 6], 'src/Views/buchungen/wertpapierfelder.php' => ['stueck' => 6, 'kurs' => 6], 'src/Views/wertpapiere/stammdaten.php' => ['kurs' => 6], 'src/Views/vertraege/kredite.php' => ['zinssatz' => 3], ]; foreach ($felder as $datei => $namen) { $html = $this->lies($datei); foreach ($namen as $name => $stellen) { $this->assert( (bool)preg_match( '/name="' . $name . '"[^>]*data-nachkommastellen="' . $stellen . '"/', $html ), "$datei: „$name“ übernimmt $stellen Nachkommastellen" ); } } } private function lies(string $pfad): string { return (string)file_get_contents($this->wurzel . '/' . $pfad); } }