Skip to content

Commit 8f7494c

Browse files
Ensure guideline file content ends with a newline (#113)
* Ensure file content ends with a newline * Update GuidelineWriterTest * Test to avoid adding extra newline --------- Co-authored-by: Ashley Hindle <ashleyhindle@users.noreply.github.com>
1 parent 92d442e commit 8f7494c

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

src/Install/GuidelineWriter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ public function write(string $guidelines): int
6868
$newContent = $frontMatter.$existingContent.$separatingNewlines.$replacement;
6969
}
7070

71+
// Ensure file content ends with a newline
72+
if (! str_ends_with($newContent, "\n")) {
73+
$newContent .= "\n";
74+
}
75+
7176
if (ftruncate($handle, 0) === false || fseek($handle, 0) === -1) {
7277
throw new RuntimeException("Failed to reset file pointer: {$filePath}");
7378
}

tests/Unit/Install/GuidelineWriterTest.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
$writer->write('test guidelines content');
6161

6262
$content = file_get_contents($tempFile);
63-
expect($content)->toBe("<laravel-boost-guidelines>\ntest guidelines content\n</laravel-boost-guidelines>");
63+
expect($content)->toBe("<laravel-boost-guidelines>\ntest guidelines content\n</laravel-boost-guidelines>\n");
6464

6565
unlink($tempFile);
6666
});
@@ -77,7 +77,7 @@
7777
$writer->write('new guidelines');
7878

7979
$content = file_get_contents($tempFile);
80-
expect($content)->toBe("# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>");
80+
expect($content)->toBe("# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n");
8181

8282
unlink($tempFile);
8383
});
@@ -95,7 +95,30 @@
9595
$writer->write('updated guidelines');
9696

9797
$content = file_get_contents($tempFile);
98-
expect($content)->toBe("# Header\n\n<laravel-boost-guidelines>\nupdated guidelines\n</laravel-boost-guidelines>\n\n# Footer");
98+
expect($content)->toBe("# Header\n\n<laravel-boost-guidelines>\nupdated guidelines\n</laravel-boost-guidelines>\n\n# Footer\n");
99+
100+
unlink($tempFile);
101+
});
102+
103+
test('it avoids adding extra newline if one already exists', function () {
104+
$tempFile = tempnam(sys_get_temp_dir(), 'boost_test_');
105+
$initialContent = "# Header\n\n<laravel-boost-guidelines>\nold guidelines\n</laravel-boost-guidelines>\n\n# Footer\n";
106+
file_put_contents($tempFile, $initialContent);
107+
108+
$agent = Mockery::mock(Agent::class);
109+
$agent->shouldReceive('guidelinesPath')->andReturn($tempFile);
110+
$agent->shouldReceive('frontmatter')->andReturn(false);
111+
112+
$writer = new GuidelineWriter($agent);
113+
$writer->write('updated guidelines');
114+
115+
$content = file_get_contents($tempFile);
116+
expect($content)->toBe("# Header\n\n<laravel-boost-guidelines>\nupdated guidelines\n</laravel-boost-guidelines>\n\n# Footer\n");
117+
118+
// Assert no double newline at the end
119+
expect(substr($content, -2))->not->toBe("\n\n");
120+
// Assert still ends with exactly one newline
121+
expect(substr($content, -1))->toBe("\n");
99122

100123
unlink($tempFile);
101124
});
@@ -114,7 +137,7 @@
114137

115138
$content = file_get_contents($tempFile);
116139
// Should replace in-place, preserving structure
117-
expect($content)->toBe("Start\n<laravel-boost-guidelines>\nsingle line\n</laravel-boost-guidelines>\nEnd");
140+
expect($content)->toBe("Start\n<laravel-boost-guidelines>\nsingle line\n</laravel-boost-guidelines>\nEnd\n");
118141

119142
unlink($tempFile);
120143
});
@@ -133,7 +156,7 @@
133156

134157
$content = file_get_contents($tempFile);
135158
// Should replace first occurrence, second block remains untouched due to non-greedy matching
136-
expect($content)->toBe("Start\n<laravel-boost-guidelines>\nreplacement\n</laravel-boost-guidelines>\nMiddle\n<laravel-boost-guidelines>\nsecond\n</laravel-boost-guidelines>\nEnd");
159+
expect($content)->toBe("Start\n<laravel-boost-guidelines>\nreplacement\n</laravel-boost-guidelines>\nMiddle\n<laravel-boost-guidelines>\nsecond\n</laravel-boost-guidelines>\nEnd\n");
137160

138161
unlink($tempFile);
139162
});
@@ -165,7 +188,7 @@
165188
$writer->write('my guidelines');
166189

167190
$content = file_get_contents($tempFile);
168-
expect($content)->toBe("# Title\n\nParagraph 1\n\nParagraph 2\n\n===\n\n<laravel-boost-guidelines>\nmy guidelines\n</laravel-boost-guidelines>");
191+
expect($content)->toBe("# Title\n\nParagraph 1\n\nParagraph 2\n\n===\n\n<laravel-boost-guidelines>\nmy guidelines\n</laravel-boost-guidelines>\n");
169192

170193
unlink($tempFile);
171194
});
@@ -182,7 +205,7 @@
182205
$writer->write('first guidelines');
183206

184207
$content = file_get_contents($tempFile);
185-
expect($content)->toBe("<laravel-boost-guidelines>\nfirst guidelines\n</laravel-boost-guidelines>");
208+
expect($content)->toBe("<laravel-boost-guidelines>\nfirst guidelines\n</laravel-boost-guidelines>\n");
186209

187210
unlink($tempFile);
188211
});
@@ -199,7 +222,7 @@
199222
$writer->write('clean guidelines');
200223

201224
$content = file_get_contents($tempFile);
202-
expect($content)->toBe("<laravel-boost-guidelines>\nclean guidelines\n</laravel-boost-guidelines>");
225+
expect($content)->toBe("<laravel-boost-guidelines>\nclean guidelines\n</laravel-boost-guidelines>\n");
203226

204227
unlink($tempFile);
205228
});
@@ -218,7 +241,7 @@
218241

219242
expect($result)->toBe(GuidelineWriter::REPLACED);
220243
$content = file_get_contents($tempFile);
221-
expect($content)->toBe("# Title\n\n<other-rules>\nShould not be touched\n</other-rules>\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n\n<custom-config>\nAlso untouched\n</custom-config>");
244+
expect($content)->toBe("# Title\n\n<other-rules>\nShould not be touched\n</other-rules>\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n\n<custom-config>\nAlso untouched\n</custom-config>\n");
222245

223246
unlink($tempFile);
224247
});
@@ -248,7 +271,7 @@
248271
->and($content)->toContain('More content here.');
249272

250273
// Verify exact structure
251-
expect($content)->toBe("# My Project\n\n<laravel-boost-guidelines>\nupdated guidelines from boost\n</laravel-boost-guidelines>\n\n# User Added Section\nThis content was added by the user after the guidelines.\n\n## Another user section\nMore content here.");
274+
expect($content)->toBe("# My Project\n\n<laravel-boost-guidelines>\nupdated guidelines from boost\n</laravel-boost-guidelines>\n\n# User Added Section\nThis content was added by the user after the guidelines.\n\n## Another user section\nMore content here.\n");
252275

253276
unlink($tempFile);
254277
});
@@ -269,7 +292,7 @@
269292
$writer->write('new guidelines');
270293

271294
$content = file_get_contents($tempFile);
272-
expect($content)->toBe("---\nalwaysApply: true\n---\n# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>");
295+
expect($content)->toBe("---\nalwaysApply: true\n---\n# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n");
273296

274297
unlink($tempFile);
275298
});
@@ -286,7 +309,7 @@
286309
$writer->write('new guidelines');
287310

288311
$content = file_get_contents($tempFile);
289-
expect($content)->toBe("---\ncustomOption: true\n---\n# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>");
312+
expect($content)->toBe("---\ncustomOption: true\n---\n# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n");
290313

291314
unlink($tempFile);
292315
});
@@ -304,7 +327,7 @@
304327

305328
expect($result)->toBe(GuidelineWriter::NEW);
306329
$content = file_get_contents($tempFile);
307-
expect($content)->toBe("# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>");
330+
expect($content)->toBe("# Existing content\n\nSome text here.\n\n===\n\n<laravel-boost-guidelines>\nnew guidelines\n</laravel-boost-guidelines>\n");
308331

309332
unlink($tempFile);
310333
});

0 commit comments

Comments
 (0)