Skip to content

Fix more logic around newlines at EOF - this time stuff I recently broke in (pre-release) changes to applyPatch #536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/patch/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,18 @@ export function applyPatch(source, uniDiff, options = {}) {
} else if (prevLine[0] == '-') {
addEOFNL = true;
}
break;
}
prevLine = line;
}
if (removeEOFNL) {
if (lines[lines.length - 1] == '') {
if (addEOFNL) {
// This means the final line gets changed but doesn't have a trailing newline in either the
// original or patched version. In that case, we do nothing if fuzzFactor > 0, and if
// fuzzFactor is 0, we simply validate that the source file has no trailing newline.
if (!fuzzFactor && lines[lines.length - 1] == '') {
return false;
}
} else if (lines[lines.length - 1] == '') {
lines.pop();
} else if (!fuzzFactor) {
return false;
Expand Down
35 changes: 35 additions & 0 deletions test/patch/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,41 @@ describe('patch/apply', function() {
expect(applyPatch(oldFile, diffFile, {fuzzFactor: 1})).to.equal(oldFile);
});

describe('when the last line is changed but both old & new version have no trailing newline...', () => {
const diffFile = 'Index: file.txt\n' +
'===================================================================\n' +
'--- file.txt\n' +
'+++ file.txt\n' +
'@@ -1,4 +1,4 @@\n' +
' foo\n' +
' bar\n' +
' baz\n' +
'-banana\n' +
'\\ No newline at end of file\n' +
'+babaco\n' +
'\\ No newline at end of file\n';

it('correctly applies the patch to the original source file', () => {
const oldFile = 'foo\nbar\nbaz\nbanana';
expect(applyPatch(oldFile, diffFile)).to.equal('foo\nbar\nbaz\nbabaco');
});

it('fails if fuzzFactor=0 and the source file has an unexpected trailing newline', () => {
const oldFile = 'foo\nbar\nbaz\nbanana\n';
expect(applyPatch(oldFile, diffFile)).to.equal(false);
});

it('ignores an unexpected trailing newline if fuzzFactor > 0', () => {
const oldFile = 'foo\nbar\nbaz\nbanana\n';
expect(applyPatch(oldFile, diffFile, {fuzzFactor: 1})).to.equal('foo\nbar\nbaz\nbabaco\n');
});

it("ignores extra lines, even with fuzzFactor = 0, as long as there's no newline at EOF", () => {
const oldFile = 'foo\nbar\nbaz\nbanana\nqux';
expect(applyPatch(oldFile, diffFile)).to.equal('foo\nbar\nbaz\nbabaco\nqux');
});
});

it('rejects negative or non-integer fuzz factors', () => {
expect(() => {
applyPatch(
Expand Down