true, 'verboseOutput' => true ]); function mkfile(string $body): void { $post = fopen(ROOT."/blog/dietrannynigger.md", "w"); fwrite($post, "title: 【】\n"); fwrite($post, "uuid: ".uuid()."\n"); fwrite($post, "author: 諏訪子\n"); fwrite($post, "date: ".date("Y-m-d H:i:s")."\n"); fwrite($post, "thumbnail: \n"); fwrite($post, "thumborient: center\n"); fwrite($post, "category: \n"); fwrite($post, "----\n"); fwrite($post, $body); fclose($post); } function rmfile(): void { if (is_file(ROOT."/blog/dietrannynigger.md")) unlink(ROOT."/blog/dietrannynigger.md"); } class Constants { public const START = "
"; public const END = "
"; } $test->describe('マークダウン', function($test): void { // サンプルの投稿が無いと、Markdownは404にリダイレクトしてexitするので、テスト全体が止まる。 // 一時的な投稿もblog/に書くので、サイト(本番)では動かさない if (!is_file(ROOT.'/blog/feature-test.md')) { $test->skipAll('サンプルの投稿(blog/feature-test.md)が無い'); } $test->it('メタデータをパーシング出来るはず', function($test): void { $md = new Markdown('feature-test', '/blog/'); $test->assertNotNull($md); $meta = $md->getMetadata(); $test->assertNotNull($meta); $expect = new \stdClass; $expect->title = '【マークダウン】関数'; $expect->uuid = 'a8c04518-4181-4ec6-9ef0-3f88f23b84b6'; $expect->author = '諏訪子'; $expect->date = '2025-11-07 20:33:42'; $expect->thumbnail = 'o_53803618dc1691.28179609-orig.jpg'; $expect->thumborient = 'center'; $expect->category = ['test', 'おちんちん', 'でっかいおっぱい']; $expect->css = ['code', 'blockquote', 'table', 'blink']; $test->assertEquals($expect, $meta); }); $test->it('横線はHTMLに交換出来るはず', function($test): void { mkfile('----'); $md = new Markdown('dietrannynigger', '/blog/'); $test->assertNotNull($md); $body = $md->parse(); $test->assertNotNull($body); $expect = "')); $test->assertStringContains('前の行後の行', $body); }); $test->it('「/*」から「*/」までは無視されるはず', function($test): void { mkfile("# 見出し\n/* 1行目\n\n# コメントの中の見出し\n最後の行 */\n本文\n/* 1行だけ */\n/* 後ろに文字 */ 残る\n\n- リスト"); $body = (new Markdown('dietrannynigger', '/blog/'))->parse(); $test->assertFalse(str_contains($body, '1行目')); $test->assertFalse(str_contains($body, 'コメントの中の見出し')); $test->assertFalse(str_contains($body, '最後の行')); $test->assertFalse(str_contains($body, '1行だけ')); $test->assertFalse(str_contains($body, '後ろに文字')); $test->assertStringContains('本文', $body); $test->assertStringContains('残る', $body); $test->assertStringContains('
'));
});
$test->it('コードブロックの中のコメントは表示されるはず', function($test): void {
mkfile("```c\n// Cのコメント\n/* ブロック */\nint x;\n```\n\n```txt\n/* 開いたまま\n```\n\n後の段落");
$body = (new Markdown('dietrannynigger', '/blog/'))->parse();
$test->assertStringContains('// Cのコメント', $body);
$test->assertStringContains('/* ブロック */', $body);
$test->assertStringContains('/* 開いたまま', $body);
// コードブロックの中の「/*」はコメントを始めない
$test->assertStringContains('後の段落', $body);
});
$test->it('コメントはプレビュー用にも取り除けるはず', function($test): void {
$test->assertEquals("a\nb\n```\n// c\n```", Markdown::stripComments("a\r\n// x\r\n/* y\r\nz */\r\nb\r\n```\r\n// c\r\n```"));
});
$test->it('URLの「//」や行の途中の「/*」はコメントではないはず', function($test): void {
mkfile("https://076.moe/ の // と /* は行の途中\n次の行");
$body = (new Markdown('dietrannynigger', '/blog/'))->parse();
$test->assertStringContains('https://076.moe/ の // と /* は行の途中', $body);
$test->assertStringContains('次の行', $body);
});
$test->it('画像、音楽、動画はHTMLに交換出来るはず', function($test): void {
mkfile("\n
\n
\n
$[audio/ogg](https://ass.technicalsuwako.moe/砕月着信音.ogg)\n
#[video/mp4](https://ass.technicalsuwako.moe/フリーズ.mp4)");
$md = new Markdown('dietrannynigger', '/blog/');
$test->assertNotNull($md);
$body = $md->parse();
$test->assertNotNull($body);
$expect = '
'
. '
'
. '
'
. '
'
. '
';
$actual = str_replace("\n", '', str_replace(' ', '', trim($body)));
$test->assertEquals($expect, $actual);
});
$test->it('基本的なマークダウンはHTMLに交換出来るはず', function($test): void {
mkfile("**太文字**\n
*イタリック*\n
_下線_\n
~取消線~\n
!:(5)明滅文字:!\n
^(72)フォントサイズ^\n
%(ff00ff)フォントカラー%");
$md = new Markdown('dietrannynigger', '/blog/');
$test->assertNotNull($md);
$body = $md->parse();
$test->assertNotNull($body);
$expect = ' 太文字
'
. ' イタリック
'
. ' 下線
'
. ' 取消線
'
. ' 明滅文字
'
. ' フォントサイズ
'
. ' フォントカラー
';
$actual = str_replace("\n", '', trim($body));
$test->assertEquals($expect, $actual);
});
$test->it('複数マークダウンはHTMLに交換出来るはず', function($test): void {
mkfile("[^(500)(すわこ)](https://techsuwako.jp/)^");
$md = new Markdown('dietrannynigger', '/blog/');
$test->assertNotNull($md);
$body = $md->parse();
$test->assertNotNull($body);
$expect = Constants::START.'God'.Constants::END;
$actual = str_replace("\n", '', trim($body));
$test->assertEquals($expect, $actual);
});
$test->it('インライン数式はMathMLに交換出来るはず', function($test): void {
mkfile('長さは$$\lVert \mathbf{v} \rVert = \sqrt{x^2 + y^2}$$です。');
$md = new Markdown('dietrannynigger', '/blog/');
$body = $md->parse();
$test->assertStringContains('