Skip to content

Commit c1ab3f9

Browse files
CodeRabbit Generated Unit Tests: Add framework-specific .gitignore validation tests and placeholder
1 parent 9f24b9b commit c1ab3f9

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

tests/GitignoreValidationTest.php

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
/**
3+
* Test Framework: PHPUnit
4+
* Purpose: Validate critical .gitignore patterns are present and consistent.
5+
*/
6+
use PHPUnit\Framework\TestCase;
7+
8+
final class GitignoreValidationTest extends TestCase
9+
{
10+
private static $path = __DIR__ . '/../.gitignore';
11+
private static $expected = [
12+
// OS-specific
13+
'.DS_Store',
14+
'Thumbs.db',
15+
'ehthumbs.db',
16+
'Desktop.ini',
17+
// Temp/log/backup
18+
'*.log',
19+
'*.tmp',
20+
'*.swp',
21+
'*.swo',
22+
'*.bak',
23+
'*.orig',
24+
// Secrets
25+
'.env',
26+
'.env.*',
27+
'*.key',
28+
'*.pem',
29+
// Build/cache
30+
'dist/',
31+
'build/',
32+
'out/',
33+
'tmp/',
34+
'cache/',
35+
'*.pyc',
36+
'__pycache__/',
37+
// IDE
38+
'.vscode/',
39+
'.history/',
40+
'.idea/',
41+
// Node
42+
'node_modules/',
43+
'npm-debug.log',
44+
'yarn-error.log',
45+
'*.lock',
46+
// PHP
47+
'vendor/',
48+
'composer.phar',
49+
'.phpunit.result.cache',
50+
'phpunit.xml.dist',
51+
'.php-cs-fixer.cache',
52+
'.phpstan/',
53+
'psalm.xml.dist',
54+
'storage/',
55+
'bootstrap/cache/',
56+
'var/',
57+
'*.cache',
58+
'.env.backup',
59+
'.env.local',
60+
'.env.production',
61+
'.env.testing',
62+
'homestead.yaml',
63+
'Homestead.yaml',
64+
'Homestead.json',
65+
// WordPress
66+
'wp-content/uploads/',
67+
'wp-content/cache/',
68+
'wp-content/upgrade/',
69+
'wp-content/debug.log',
70+
// Coverage
71+
'coverage/',
72+
'*.lcov',
73+
// Other binaries
74+
'*.iml',
75+
'*.class',
76+
'*.o',
77+
'*.out',
78+
'*.so',
79+
'*.dll',
80+
'*.exe',
81+
'*.pid',
82+
];
83+
84+
private function readGitignore(): array
85+
{
86+
$this->assertFileExists(self::$path, ".gitignore must exist at repo root.");
87+
$content = file_get_contents(self::$path);
88+
$this->assertNotFalse($content, "Failed to read .gitignore");
89+
// Normalize line endings and trim trailing spaces
90+
$lines = preg_split('/\R/u', $content);
91+
return array_map(static function ($l) {
92+
return rtrim($l, " \t");
93+
}, $lines);
94+
}
95+
96+
public function test_expected_patterns_are_present(): void
97+
{
98+
$lines = $this->readGitignore();
99+
$set = array_flip($lines);
100+
foreach (self::$expected as $pattern) {
101+
$this->assertArrayHasKey($pattern, $set, "Missing required .gitignore entry: {$pattern}");
102+
}
103+
}
104+
105+
public function test_no_trailing_whitespace_on_rule_lines(): void
106+
{
107+
$content = file_get_contents(self::$path);
108+
$this->assertNotFalse($content);
109+
$bad = [];
110+
$i = 0;
111+
foreach (preg_split('/\R/u', $content) as $line) {
112+
$i++;
113+
if ($line !== '' && $line[0] !== '#') {
114+
if (preg_match('/[ \t]+$/', $line)) {
115+
$bad[] = $i;
116+
}
117+
}
118+
}
119+
$this->assertCount(0, $bad, "Trailing whitespace detected on lines: " . implode(', ', $bad));
120+
}
121+
122+
public function test_has_trailing_newline_at_eof(): void
123+
{
124+
$content = file_get_contents(self::$path);
125+
$this->assertNotFalse($content);
126+
$this->assertTrue(substr($content, -1) === "\n", "Expected .gitignore to end with a newline.");
127+
}
128+
129+
public function test_no_duplicate_rules(): void
130+
{
131+
$lines = $this->readGitignore();
132+
$counts = [];
133+
foreach ($lines as $line) {
134+
if ($line === '' || str_starts_with($line, '#')) continue;
135+
$counts[$line] = ($counts[$line] ?? 0) + 1;
136+
}
137+
$dupes = array_keys(array_filter($counts, fn($c) => $c > 1));
138+
$this->assertEmpty($dupes, "Duplicate .gitignore rules found: " . implode(', ', $dupes));
139+
}
140+
141+
public function test_section_headers_exist(): void
142+
{
143+
$lines = $this->readGitignore();
144+
$headers = [
145+
'# OS依存ファイル',
146+
'# 一時ファイル・ログ・バックアップ',
147+
'# 環境変数・機密情報',
148+
'# ビルド成果物・キャッシュ',
149+
'# IDE / エディタ設定',
150+
'# Node.js関連',
151+
'# PHP関連設定',
152+
'# カバレッジ関連',
153+
'# その他',
154+
];
155+
$set = array_flip($lines);
156+
foreach ($headers as $h) {
157+
$this->assertArrayHasKey($h, $set, "Missing section header: {$h}");
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)