HTMLを綺麗に、色んなテスト関係関数の修正
諏訪子 <suwako@076.moe>、2025-11-20 22:39
コミット 4f70e6d4e4717aa3c3df7466e331b3aea7d9a5f2
・親 8513c53
・ファイルを見る
11個のファイル、+144 -70
| @@ -56,7 +56,7 @@ | ||
| 56 | 56 | ##### ケロケロ |
| 57 | 57 | [076スタジオ合同会社](https://076.moe/)\ |
| 58 | 58 | <諏訪子>(すわこ)\ |
| 59 | -`int i = 0;`\ | |
| 59 | +`int i = 0;` | |
| 60 | 60 | |
| 61 | 61 | ###### ケロケロ |
| 62 | 62 | 1. アセンブリ言語 |
| @@ -69,7 +69,7 @@ | ||
| 69 | 69 | // 各ファイルにHTMLの出力の作成 |
| 70 | 70 | $html = ''; |
| 71 | 71 | foreach ($fileDiffs as $fileName => $diff) { |
| 72 | - $html .= "<h2>ファイル: ".htmlspecialchars($fileName)."</h2>\n"; | |
| 72 | + $html .= "\n <h2>ファイル: ".htmlspecialchars($fileName)."</h2>\n"; | |
| 73 | 73 | $html .= $this->generateHtml($diff['leftLines'], $diff['rightLines']); |
| 74 | 74 | } |
| 75 | 75 | |
| @@ -106,25 +106,25 @@ | ||
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | private function generateHtml(array $leftLines, array $rightLines): string { |
| 109 | - $html = '<table class="diff-table">'; | |
| 110 | - $html .= '<tr class="diff-header"><th colspan="2">前</th><th colspan="2">新</th></tr>'; | |
| 109 | + $html = " <p>\n <table class=\"diff-table\">\n"; | |
| 110 | + $html .= " <tr class=\"diff-header\"><th colspan=\"2\">前</th><th colspan=\"2\">新</th></tr>\n"; | |
| 111 | 111 | |
| 112 | 112 | $maxLines = max(count($leftLines), count($rightLines)); |
| 113 | 113 | for ($i = 0; $i < $maxLines; $i++) { |
| 114 | 114 | $left = isset($leftLines[$i]) ? $leftLines[$i] : ['content' => '', 'type' => 'empty', 'line' => '']; |
| 115 | 115 | $right = isset($rightLines[$i]) ? $rightLines[$i] : ['content' => '', 'type' => 'empty', 'line' => '']; |
| 116 | 116 | |
| 117 | - $html .= '<tr>'; | |
| 117 | + $html .= " <tr>\n"; | |
| 118 | 118 | // 左(変更前) |
| 119 | - $html .= '<td class="line-number">' . ($left['line'] ?: ' ') . '</td>'; | |
| 120 | - $html .= '<td class="' . $left['type'] . '">' . ($left['content'] ?: ' ') . '</td>'; | |
| 119 | + $html .= " <td class=\"line-number\">".($left['line'] ?: ' ')."</td>\n"; | |
| 120 | + $html .= " <td class=\"{$left['type']}\">".($left['content'] ?: ' ')."</td>\n"; | |
| 121 | 121 | // 右(変更後) |
| 122 | - $html .= '<td class="line-number">' . ($right['line'] ?: ' ') . '</td>'; | |
| 123 | - $html .= '<td class="' . $right['type'] . '">' . ($right['content'] ?: ' ') . '</td>'; | |
| 124 | - $html .= '</tr>'; | |
| 122 | + $html .= " <td class=\"line-number\">".($right['line'] ?: ' ')."</td>\n"; | |
| 123 | + $html .= " <td class=\"{$right['type']}\">".($right['content'] ?: ' ')."</td>\n"; | |
| 124 | + $html .= " </tr>\n"; | |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | - $html .= '</table>'; | |
| 127 | + $html .= " </table>\n </p>\n"; | |
| 128 | 128 | return $html; |
| 129 | 129 | } |
| 130 | 130 | } |
| @@ -98,7 +98,7 @@ | ||
| 98 | 98 | if (preg_match('/^```(\w*)$/', $line, $matches)) { |
| 99 | 99 | if (!$this->inCodeBlock) { |
| 100 | 100 | if (!empty($currentParagraph)) { |
| 101 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 101 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 102 | 102 | $currentParagraph = []; |
| 103 | 103 | } |
| 104 | 104 | $this->inCodeBlock = true; |
| @@ -121,7 +121,7 @@ | ||
| 121 | 121 | // テーブルの処理 |
| 122 | 122 | if (preg_match('/^\|(.+)\|$/', $line)) { |
| 123 | 123 | if (!empty($currentParagraph)) { |
| 124 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 124 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 125 | 125 | $currentParagraph = []; |
| 126 | 126 | } |
| 127 | 127 | $cells = array_map('trim', explode('|', trim($line, '|'))); |
| @@ -145,17 +145,17 @@ | ||
| 145 | 145 | // 水平線の処理 |
| 146 | 146 | if (preg_match('/^([\-\*\_])\1{2,}$/', $line)) { |
| 147 | 147 | if (!empty($currentParagraph)) { |
| 148 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 148 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 149 | 149 | $currentParagraph = []; |
| 150 | 150 | } |
| 151 | - $this->html[] = "<hr>"; | |
| 151 | + $this->html[] = " <hr />\n"; | |
| 152 | 152 | continue; |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | // 引用ブロックの処理 |
| 156 | 156 | if (preg_match('/^>\s(.+)/', $line, $matches)) { |
| 157 | 157 | if (!empty($currentParagraph)) { |
| 158 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 158 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 159 | 159 | $currentParagraph = []; |
| 160 | 160 | } |
| 161 | 161 | $inBlockquote = true; |
| @@ -176,7 +176,7 @@ | ||
| 176 | 176 | $inList = false; |
| 177 | 177 | } |
| 178 | 178 | if (!empty($currentParagraph)) { |
| 179 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 179 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 180 | 180 | $currentParagraph = []; |
| 181 | 181 | } |
| 182 | 182 | |
| @@ -191,19 +191,19 @@ | ||
| 191 | 191 | $inList = false; |
| 192 | 192 | } |
| 193 | 193 | if (!empty($currentParagraph)) { |
| 194 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 194 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 195 | 195 | $currentParagraph = []; |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | $level = strlen($m[1]); |
| 199 | - $this->html[] = "<h{$level}>".$this->parseInline($m[2])."</h{$level}>"; | |
| 199 | + $this->html[] = " <h{$level}>".$this->parseInline($m[2])."</h{$level}>"; | |
| 200 | 200 | continue; |
| 201 | 201 | } |
| 202 | 202 | |
| 203 | 203 | // 箇条書きリスト |
| 204 | 204 | if (preg_match('/^(\s*)([\*\-])\s(.+)/', $line, $m)) { |
| 205 | 205 | if (!empty($currentParagraph)) { |
| 206 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 206 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 207 | 207 | $currentParagraph = []; |
| 208 | 208 | } |
| 209 | 209 | $inList = true; |
| @@ -221,7 +221,7 @@ | ||
| 221 | 221 | // 番号付きリスト |
| 222 | 222 | if (preg_match('/^(\s*)\d+\.\s(.+)/', $line, $m)) { |
| 223 | 223 | if (!empty($currentParagraph)) { |
| 224 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 224 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 225 | 225 | $currentParagraph = []; |
| 226 | 226 | } |
| 227 | 227 | $inList = true; |
| @@ -246,7 +246,7 @@ | ||
| 246 | 246 | $parsedLine = $this->parseInline($line); |
| 247 | 247 | $currentParagraph[] = $parsedLine; |
| 248 | 248 | if ($hasBR) { |
| 249 | - $currentParagraph[] = "<br />"; | |
| 249 | + $currentParagraph[] = "<br />\n "; | |
| 250 | 250 | } |
| 251 | 251 | } |
| 252 | 252 | |
| @@ -254,7 +254,7 @@ | ||
| 254 | 254 | if ($inBlockquote) $this->html[] = $this->createBlockquote($blockquoteContent); |
| 255 | 255 | if ($inTable) $this->html[] = $this->createTable($tableHeaders, $tableRows); |
| 256 | 256 | if (!empty($currentParagraph)) |
| 257 | - $this->html[] = " <p>".implode("", $currentParagraph)."</p>"; | |
| 257 | + $this->html[] = " <p>\n ".implode("", $currentParagraph)."\n </p>"; | |
| 258 | 258 | |
| 259 | 259 | return implode("\n", $this->html); |
| 260 | 260 | } |
| @@ -456,11 +456,11 @@ | ||
| 456 | 456 | $currentType = $item['type']; |
| 457 | 457 | } |
| 458 | 458 | |
| 459 | - $html .= "<{$currentType}>\n"; | |
| 459 | + $html .= " <p>\n <{$currentType}>\n"; | |
| 460 | 460 | foreach ($items as $item) { |
| 461 | - $html .= str_repeat(' ', $currentLevel)." <li>".$item['content']."</li>\n"; | |
| 461 | + $html .= str_repeat(' ', $currentLevel)." <li>".$item['content']."</li>\n"; | |
| 462 | 462 | } |
| 463 | - $html .= "</{$currentType}>"; | |
| 463 | + $html .= " </{$currentType}>\n </p>"; | |
| 464 | 464 | |
| 465 | 465 | while (!empty($listStack)) { |
| 466 | 466 | $html .= str_repeat(' ', $currentLevel)."</".array_pop($listStack).">\n"; |
| @@ -478,7 +478,7 @@ | ||
| 478 | 478 | private function createCodeBlock(): string { |
| 479 | 479 | $code = htmlspecialchars(implode("\n", $this->codeBlockContent)); |
| 480 | 480 | $class = $this->codeBlockLanguage ? " class=\"language-{$this->codeBlockLanguage}\"" : ''; |
| 481 | - return "<pre><code{$class}>{$code}</code></pre>"; | |
| 481 | + return " <p>\n <pre><code{$class}>{$code}</code></pre>"; | |
| 482 | 482 | // $raw = implode("\n", $this->codeBlockContent); |
| 483 | 483 | // $lang = $this->codeBlockLanguage ?: 'txt'; |
| 484 | 484 | // $class = $lang === 'txt' ? '' : " class=\"language-{$lang}\""; |
| @@ -487,7 +487,7 @@ | ||
| 487 | 487 | } |
| 488 | 488 | |
| 489 | 489 | private function createBlockquote(array $content): string { |
| 490 | - return "<blockquote>\n <p>".implode("</p>\n <p>", $content)."</p>\n</blockquote>"; | |
| 490 | + return " <p>\n <blockquote>\n ".implode("<br />\n ", $content)."\n </blockquote>\n </p>"; | |
| 491 | 491 | } |
| 492 | 492 | |
| 493 | 493 | /** |
| @@ -498,31 +498,31 @@ | ||
| 498 | 498 | * @return string HTMLのテーブル |
| 499 | 499 | */ |
| 500 | 500 | private function createTable(array $headers, array $rows): string { |
| 501 | - $html = "<table>\n"; | |
| 501 | + $html = " <p>\n <table>\n"; | |
| 502 | 502 | |
| 503 | 503 | // ヘッダーを追加 |
| 504 | 504 | if (!empty($headers)) { |
| 505 | - $html .= " <thead>\n <tr>\n"; | |
| 505 | + $html .= " <thead>\n <tr>\n"; | |
| 506 | 506 | foreach ($headers as $header) { |
| 507 | - $html .= " <th>".$this->parseInline($header)."</th>\n"; | |
| 507 | + $html .= " <th>".$this->parseInline($header)."</th>\n"; | |
| 508 | 508 | } |
| 509 | - $html .= " </tr>\n </thead>\n"; | |
| 509 | + $html .= " </tr>\n </thead>\n"; | |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | 512 | // 行を追加 |
| 513 | 513 | if (!empty($rows)) { |
| 514 | - $html .= " <tbody>\n"; | |
| 514 | + $html .= " <tbody>\n"; | |
| 515 | 515 | foreach ($rows as $row) { |
| 516 | - $html .= " <tr>\n"; | |
| 516 | + $html .= " <tr>\n"; | |
| 517 | 517 | foreach ($row as $cell) { |
| 518 | - $html .= " <td>".$this->parseInline($cell)."</td>\n"; | |
| 518 | + $html .= " <td>".$this->parseInline($cell)."</td>\n"; | |
| 519 | 519 | } |
| 520 | - $html .= " </tr>\n"; | |
| 520 | + $html .= " </tr>\n"; | |
| 521 | 521 | } |
| 522 | - $html .= " </tbody>\n"; | |
| 522 | + $html .= " </tbody>\n"; | |
| 523 | 523 | } |
| 524 | 524 | |
| 525 | - $html .= "</table>"; | |
| 525 | + $html .= " </table>\n </p>"; | |
| 526 | 526 | return $html; |
| 527 | 527 | } |
| 528 | 528 |
| @@ -81,7 +81,7 @@ | ||
| 81 | 81 | $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); |
| 82 | 82 | if ($this->socket === false) { |
| 83 | 83 | $msg = 'ソケットの作成に失敗: '.socket_strerror(socket_last_error()); |
| 84 | - logger(\LogType::MySQL, $msg); | |
| 84 | + \logger(\LogType::MySQL, $msg); | |
| 85 | 85 | throw new \Exception($msg); |
| 86 | 86 | } |
| 87 | 87 | |
| @@ -89,7 +89,7 @@ | ||
| 89 | 89 | if ($res === false) { |
| 90 | 90 | $msg = 'ソケットに接続に失敗: ' |
| 91 | 91 | .socket_strerror(socket_last_error($this->socket)); |
| 92 | - logger(\LogType::MySQL, $msg); | |
| 92 | + \logger(\LogType::MySQL, $msg); | |
| 93 | 93 | throw new \Exception($msg); |
| 94 | 94 | } |
| 95 | 95 | |
| @@ -102,7 +102,7 @@ | ||
| 102 | 102 | $code = unpack('v', substr($response, 1, 2))[1]; |
| 103 | 103 | $mes = substr($response, 3); |
| 104 | 104 | $msg = "認証応答に失敗: {$code} - {$mes}"; |
| 105 | - logger(\LogType::MySQL, $msg); | |
| 105 | + \logger(\LogType::MySQL, $msg); | |
| 106 | 106 | throw new \Exception($msg); |
| 107 | 107 | } |
| 108 | 108 | |
| @@ -151,7 +151,7 @@ | ||
| 151 | 151 | $code = unpack('v', substr($res, 1, 2))[1]; |
| 152 | 152 | $mes = substr($res, 3); |
| 153 | 153 | $msg = "データベースの選択に失敗: {$code} - {$mes}"; |
| 154 | - logger(\LogType::MySQL, $msg); | |
| 154 | + \logger(\LogType::MySQL, $msg); | |
| 155 | 155 | throw new \Exception($msg); |
| 156 | 156 | } |
| 157 | 157 | |
| @@ -179,7 +179,7 @@ | ||
| 179 | 179 | $code = unpack('v', substr($res, 1, 2))[1]; |
| 180 | 180 | $mes = substr($res, 3); |
| 181 | 181 | $msg = "準備に失敗: {$code} - {$mes}"; |
| 182 | - logger(\LogType::MySQL, $msg); | |
| 182 | + \logger(\LogType::MySQL, $msg); | |
| 183 | 183 | throw new \Exception($msg); |
| 184 | 184 | } |
| 185 | 185 | |
| @@ -236,14 +236,14 @@ | ||
| 236 | 236 | |
| 237 | 237 | if (!isset($this->prepared[$statementId])) { |
| 238 | 238 | $msg = "不正なステートメントID: {$statementId}"; |
| 239 | - logger(\LogType::MySQL, $msg); | |
| 239 | + \logger(\LogType::MySQL, $msg); | |
| 240 | 240 | throw new \Exception($msg); |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | $stmtInfo = $this->prepared[$statementId]; |
| 244 | 244 | if (count($params) != $stmtInfo['num_params']) { |
| 245 | 245 | $msg = "パラメータ数が一致しません: 期待 {$stmtInfo['num_params']}, 取得 ".count($params); |
| 246 | - logger(\LogType::MySQL, $msg); | |
| 246 | + \logger(\LogType::MySQL, $msg); | |
| 247 | 247 | throw new \Exception($msg); |
| 248 | 248 | } |
| 249 | 249 | |
| @@ -341,7 +341,7 @@ | ||
| 341 | 341 | $code = unpack('v', substr($res, 1, 2))[1]; |
| 342 | 342 | $mes = substr($res, 3); |
| 343 | 343 | $msg = "実行に失敗: {$code} - {$mes}"; |
| 344 | - logger(\LogType::MySQL, $msg); | |
| 344 | + \logger(\LogType::MySQL, $msg); | |
| 345 | 345 | throw new \Exception($msg); |
| 346 | 346 | } |
| 347 | 347 | |
| @@ -389,7 +389,7 @@ | ||
| 389 | 389 | $code = unpack('v', substr($res, 1, 2))[1]; |
| 390 | 390 | $mes = substr($res, 3); |
| 391 | 391 | $msg = "クエリに失敗: {$code} - {$mes}"; |
| 392 | - logger(\LogType::MySQL, $msg); | |
| 392 | + \logger(\LogType::MySQL, $msg); | |
| 393 | 393 | throw new \Exception($msg); |
| 394 | 394 | } |
| 395 | 395 | |
| @@ -402,7 +402,7 @@ | ||
| 402 | 402 | // @todo LOCAL INFILEリクエストの処理を実装 |
| 403 | 403 | if (ord($res[0]) === 0xFB) { |
| 404 | 404 | $msg = "LOCAL INFOリクエストは未対応です"; |
| 405 | - logger(\LogType::MySQL, $msg); | |
| 405 | + \logger(\LogType::MySQL, $msg); | |
| 406 | 406 | throw new \Exception($msg); |
| 407 | 407 | } |
| 408 | 408 | |
| @@ -490,7 +490,7 @@ | ||
| 490 | 490 | $mes = substr($res, 3); |
| 491 | 491 | $this->close(); |
| 492 | 492 | $msg = "認証に失敗: {$code} - {$mes}"; |
| 493 | - logger(\LogType::MySQL, $msg); | |
| 493 | + \logger(\LogType::MySQL, $msg); | |
| 494 | 494 | throw new \Exception($msg); |
| 495 | 495 | } |
| 496 | 496 | |
| @@ -518,7 +518,7 @@ | ||
| 518 | 518 | $eofPacket = $this->readPacket(); |
| 519 | 519 | if (ord($eofPacket[0]) !== 0xFE) { |
| 520 | 520 | $msg = "フィールド説明の後にEOFパケットが期待されます"; |
| 521 | - logger(\LogType::MySQL, $msg); | |
| 521 | + \logger(\LogType::MySQL, $msg); | |
| 522 | 522 | throw new \Exception($msg); |
| 523 | 523 | } |
| 524 | 524 | |
| @@ -664,7 +664,7 @@ | ||
| 664 | 664 | private function parseOkPacket(string $packet): array { |
| 665 | 665 | if (strlen($packet) < 2) { |
| 666 | 666 | $msg = "OKパケットが短すぎます: ".strlen($packet)."バイト"; |
| 667 | - logger(\LogType::MySQL, $msg); | |
| 667 | + \logger(\LogType::MySQL, $msg); | |
| 668 | 668 | throw new \Exception($msg); |
| 669 | 669 | } |
| 670 | 670 | |
| @@ -678,7 +678,7 @@ | ||
| 678 | 678 | |
| 679 | 679 | if (strlen($packet) < $pos + 2) { |
| 680 | 680 | $msg = "OKパケットにサーバーステータス用のデータが不足しています"; |
| 681 | - logger(\LogType::MySQL, $msg); | |
| 681 | + \logger(\LogType::MySQL, $msg); | |
| 682 | 682 | throw new \Exception($msg); |
| 683 | 683 | } |
| 684 | 684 | $serverStatus = unpack('v', substr($packet, $pos, 2))[1]; |
| @@ -686,7 +686,7 @@ | ||
| 686 | 686 | |
| 687 | 687 | if (strlen($packet) < $pos + 2) { |
| 688 | 688 | $msg = "OKパケットに警告カウント用のデータが不足しています"; |
| 689 | - logger(\LogType::MySQL, $msg); | |
| 689 | + \logger(\LogType::MySQL, $msg); | |
| 690 | 690 | throw new \Exception($msg); |
| 691 | 691 | } |
| 692 | 692 | $warningCount = unpack('v', substr($packet, $pos, 2))[1]; |
| @@ -712,7 +712,7 @@ | ||
| 712 | 712 | $bytesRead = socket_recv($this->socket, $header, 4, MSG_WAITALL); |
| 713 | 713 | if ($bytesRead !== 4) { |
| 714 | 714 | $msg = "パケットヘッダーの読み込みに失敗: 期待 4 バイト, 取得 {$bytesRead}"; |
| 715 | - logger(\LogType::MySQL, $msg); | |
| 715 | + \logger(\LogType::MySQL, $msg); | |
| 716 | 716 | throw new \Exception($msg); |
| 717 | 717 | } |
| 718 | 718 | |
| @@ -738,7 +738,7 @@ | ||
| 738 | 738 | if ($bytesRead === false) { |
| 739 | 739 | $msg = "パケット内容の読み込みに失敗: エラー " |
| 740 | 740 | .socket_strerror(socket_last_error($this->socket)); |
| 741 | - logger(\LogType::MySQL, $msg); | |
| 741 | + \logger(\LogType::MySQL, $msg); | |
| 742 | 742 | throw new \Exception($msg); |
| 743 | 743 | } |
| 744 | 744 | |
| @@ -811,7 +811,7 @@ | ||
| 811 | 811 | $sent = socket_write($this->socket, $header, 4); |
| 812 | 812 | if ($sent !== 4) { |
| 813 | 813 | $msg = "パケットヘッダーの送信に失敗"; |
| 814 | - logger(\LogType::MySQL, $msg); | |
| 814 | + \logger(\LogType::MySQL, $msg); | |
| 815 | 815 | throw new \Exception($msg); |
| 816 | 816 | } |
| 817 | 817 | |
| @@ -819,7 +819,7 @@ | ||
| 819 | 819 | $sent = socket_write($this->socket, $data, $len); |
| 820 | 820 | if ($sent !== $len) { |
| 821 | 821 | $msg = "パケットデータの送信に失敗"; |
| 822 | - logger(\LogType::MySQL, $msg); | |
| 822 | + \logger(\LogType::MySQL, $msg); | |
| 823 | 823 | throw new \Exception($msg); |
| 824 | 824 | } |
| 825 | 825 |
| @@ -19,6 +19,7 @@ | ||
| 19 | 19 | private bool $colorOutput = true; |
| 20 | 20 | private bool $verboseOutput = true; |
| 21 | 21 | private bool $stopOnFailure = false; |
| 22 | + private bool $skipCurrentDescribe = false; | |
| 22 | 23 | private array $beforeEachCallbacks = []; |
| 23 | 24 | private array $afterEachCallbacks = []; |
| 24 | 25 | private array $beforeAllCallbacks = []; |
| @@ -119,6 +120,7 @@ | ||
| 119 | 120 | */ |
| 120 | 121 | public function describe(string $description, callable $callback): Tester { |
| 121 | 122 | $this->currentTestCase = $description; |
| 123 | + $this->skipCurrentDescribe = false; | |
| 122 | 124 | $this->output($this->colorize('bold', "テストケース: {$description}")); |
| 123 | 125 | |
| 124 | 126 | try { |
| @@ -149,6 +151,11 @@ | ||
| 149 | 151 | * @return Tester このインスタンス |
| 150 | 152 | */ |
| 151 | 153 | public function it(string $description, callable $callback): Tester { |
| 154 | + if ($this->skipCurrentDescribe) { | |
| 155 | + $this->skip($description, 'skipAll() が呼び出されました'); | |
| 156 | + return $this; | |
| 157 | + } | |
| 158 | + | |
| 152 | 159 | $this->currentTest = $description; |
| 153 | 160 | $this->testCount++; |
| 154 | 161 | |
| @@ -435,7 +442,42 @@ | ||
| 435 | 442 | } |
| 436 | 443 | |
| 437 | 444 | /** |
| 438 | - * Print a summary of the test results | |
| 445 | + * コレクションが指定された要素数を持つ事 | |
| 446 | + * | |
| 447 | + * @param int $expoected 期待される要素数 | |
| 448 | + * @param iterable $collection 配列または Traversable | |
| 449 | + * @param string|null $message 失敗時のカスタムメッセージ | |
| 450 | + * @return Tester | |
| 451 | + * | |
| 452 | + * @throws AssertionFailedException | |
| 453 | + */ | |
| 454 | + public function assertCount(int $expected, iterable $collection, ?string $message = null): Tester { | |
| 455 | + $actual = is_countable($collection) ? count($collection) : iterator_count($collection); | |
| 456 | + | |
| 457 | + if ($actual !== $expected) { | |
| 458 | + $message ??= "要素数が {$expected} であることを期待しましたが、{$actual} でした"; | |
| 459 | + throw new AssertionFailedException($message); | |
| 460 | + } | |
| 461 | + | |
| 462 | + return $this; | |
| 463 | + } | |
| 464 | + | |
| 465 | + /** | |
| 466 | + * 現在の describe ブロック内の残りすべての it() をスキップ | |
| 467 | + * | |
| 468 | + * @param string $reason スキップ理由(出力に表示) | |
| 469 | + * @return void | |
| 470 | + */ | |
| 471 | + public function skipAll(string $reason = 'このテストケースはスキップされました'): void { | |
| 472 | + $this->skipCurrentDescribe = true; | |
| 473 | + | |
| 474 | + if ($this->verboseOutput) { | |
| 475 | + $this->output($this->colorize('cyan', " スキップAll: {$reason}")); | |
| 476 | + } | |
| 477 | + } | |
| 478 | + | |
| 479 | + /** | |
| 480 | + * テスト結果の詳細を表示する | |
| 439 | 481 | * |
| 440 | 482 | * @return Tester |
| 441 | 483 | */ |
| @@ -61,4 +61,6 @@ | ||
| 61 | 61 | } catch (\Exception $e) { |
| 62 | 62 | echo 'エラー: '.$e->getMessage()."\n"; |
| 63 | 63 | } |
| 64 | -}); | |
| 64 | +}); | |
| 65 | + | |
| 66 | +$test->printSummary(); |
変更
tester.php
| @@ -1,5 +1,7 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | require_once __DIR__.DIRECTORY_SEPARATOR.'/autoload.php'; |
| 3 | +define('ROOT', realpath(__DIR__)); | |
| 4 | +require_once __DIR__.DIRECTORY_SEPARATOR.'/config/config.php'; | |
| 3 | 5 | |
| 4 | 6 | $testDir = __DIR__.DIRECTORY_SEPARATOR.'src/Site/Test'; |
| 5 | 7 | $testFiles = glob($testDir.'/*.php'); |
変更
util.php
| @@ -61,3 +61,33 @@ | ||
| 61 | 61 | file_put_contents($logfile, $arg."\n", FILE_APPEND); |
| 62 | 62 | } |
| 63 | 63 | } |
| 64 | + | |
| 65 | +function to_money($amount, $lang) { | |
| 66 | + $amount = floatval($amount); | |
| 67 | + | |
| 68 | + switch (strtolower($lang)) { | |
| 69 | + case 'ja': | |
| 70 | + if ($amount >= 100000000) { | |
| 71 | + $oku = $amount / 100000000; | |
| 72 | + return $oku.'億円'; | |
| 73 | + } else if ($amount >= 10000) { | |
| 74 | + $man = $amount / 10000; | |
| 75 | + return $man.'万円'; | |
| 76 | + } | |
| 77 | + return number_format($amount, 0).'円'; | |
| 78 | + case 'en': | |
| 79 | + if ($amount >= 1000000000) { | |
| 80 | + $billion = $amount / 1000000000; | |
| 81 | + return '¥ '.$billion.' billion'; | |
| 82 | + } else if ($amount >= 1000000) { | |
| 83 | + $million = $amount / 1000000; | |
| 84 | + return '¥ '.$million.' million'; | |
| 85 | + } else if ($amount >= 1000) { | |
| 86 | + $thousand = $amount / 1000; | |
| 87 | + return '¥ '.$thousand.' thousand'; | |
| 88 | + } | |
| 89 | + return '¥ '.number_format($amount, 0); | |
| 90 | + default: | |
| 91 | + return '¥ '.number_format($amount, 0); | |
| 92 | + } | |
| 93 | +} |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | {@ include(common/header) @} |
| 2 | 2 | {@ include(common/search) @} |
| 3 | - | |
| 4 | 3 | <div class="news-article"> |
| 5 | 4 | {@ if (isset($meta->thumbnail) && $meta->thumbnail != '') @} |
| 6 | 5 | <div class="thumbnail{{ isset($meta->thumborient) && $meta->thumborient != 'center' ? ' '.$meta->thumborient : '' }}"> |
| @@ -12,16 +11,11 @@ | ||
| 12 | 11 | <div class="meta-author">{{ $meta->author }}</div> |
| 13 | 12 | {@ if (isset($meta->category) && !empty($meta->category) && $meta->category[0] !== '') @} |
| 14 | 13 | {@ foreach ($meta->category as $cat) @} |
| 15 | - <div class="meta-category"> | |
| 16 | - {{ $cat }} | |
| 17 | - | |
| 18 | - </div> | |
| 14 | + <div class="meta-category">{{ $cat }}</div> | |
| 19 | 15 | {@ endforeach @} |
| 20 | 16 | {@ endif @} |
| 21 | 17 | </div> |
| 22 | - | |
| 23 | 18 | <h1 class="title">{{{ $meta->title }}}</h1> |
| 24 | -{{{ $article }}} | |
| 25 | - | |
| 19 | +{{{ $article."\n" }}} | |
| 26 | 20 | </div> |
| 27 | 21 | {@ include(common/footer) @} |
| @@ -1,7 +1,9 @@ | ||
| 1 | 1 | </main> |
| 2 | 2 | <footer> |
| 3 | - <address>Copyright{{ defined('COPYRIGHT_YEAR') ? ' '.COPYRIGHT_YEAR : '' }} © <a href="https://076.moe/">076スタジオ合同会社</a></address><br /> | |
| 3 | + <address> | |
| 4 | + Copyright{{ defined('COPYRIGHT_YEAR') ? ' '.COPYRIGHT_YEAR : '' }} © <a href="https://076.moe/">076スタジオ合同会社</a><br /> | |
| 4 | 5 | Powered By <a href="https://technicalsuwako.moe/littlebeast">Little Beast</a> |
| 6 | + </address> | |
| 5 | 7 | </footer> |
| 6 | 8 | </div> |
| 7 | 9 | </body> |
| @@ -12,13 +12,15 @@ | ||
| 12 | 12 | {@ endforeach @} |
| 13 | 13 | {@ endif @} |
| 14 | 14 | {@ if (isset($meta)) @} |
| 15 | +{@ if (isset($meta->author)) @} | |
| 15 | 16 | <meta name="author" content="{{ $meta->author }}" /> |
| 17 | +{@ endif @} | |
| 16 | 18 | {@ if (isset($meta->thumbnail)) @} |
| 17 | 19 | <meta name="thumbnail" content="/static/{{ $meta->thumbnail }}" /> |
| 18 | 20 | {@ endif @} |
| 19 | 21 | {@ endif @} |
| 20 | 22 | <meta name="description" content="{{ $description }}" /> |
| 21 | - <meta name="keywords" content="{{ SITEINFO['tags'].',' }}{@ if (isset($meta)) @}{@ foreach ($meta->category as $cat) @}{{ $cat.',' }}{@ endforeach @}{@ endif @}" /> | |
| 23 | + <meta name="keywords" content="{{ SITEINFO['tags'].(isset($meta->category) ? ',' : '') }}{@ if (isset($meta) && isset($meta->category)) @}{@ foreach ($meta->category as $k => $cat) @}{{ $cat.($k === array_key_last($meta->category) ? '' : ',') }}{@ endforeach @}{@ endif @}" /> | |
| 22 | 24 | |
| 23 | 25 | <meta property="og:title" content="{{ SITEINFO['title'] }}: {{ $pagetit }}" /> |
| 24 | 26 | <meta property="og:description" content="{{ $description }}" /> |
| @@ -46,7 +48,7 @@ | ||
| 46 | 48 | <div class="container"> |
| 47 | 49 | <header> |
| 48 | 50 | <div class="logo"> |
| 49 | - {{ SITEINFO['title'] }} | |
| 51 | + {{ SITEINFO['title'] }}{{ "\n" }} | |
| 50 | 52 | </div> |
| 51 | 53 | <nav> |
| 52 | 54 | {@ foreach ($menu as $m) @} |