Skip to content
New issue

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

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

Already on GitHub? # to your account

Fix diffTrimmedLines not keep whitespaces in the output #219

Closed
wants to merge 1 commit into from
Closed
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
56 changes: 47 additions & 9 deletions src/diff/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,60 @@ lineDiff.tokenize = function(value) {
}

// Merge the content and line separators into single tokens
for (let i = 0; i < linesAndNewlines.length; i++) {
let line = linesAndNewlines[i];

if (i % 2 && !this.options.newlineIsToken) {
retLines[retLines.length - 1] += line;
} else {
if (this.options.ignoreWhitespace) {
line = line.trim();
if (this.options.ignoreWhitespace) {
for (let i = 0; i < linesAndNewlines.length; i++) {
let line = linesAndNewlines[i];

if (i % 2 && !this.options.newlineIsToken) {
let last = retLines[retLines.length - 1];
last.key += line;
last.payload += line;
} else {
retLines.push({ key: line.trim(), payload: line });
}
}
} else {
for (let i = 0; i < linesAndNewlines.length; i++) {
let line = linesAndNewlines[i];

if (i % 2 && !this.options.newlineIsToken) {
retLines[retLines.length - 1] += line;
} else {
retLines.push(line);
}
retLines.push(line);
}
}

return retLines;
};

lineDiff.removeEmpty = function(array) {
if (this.options.ignoreWhitespace) {
return array.filter(v => v.key);
}
return array.filter(v => v);
};

lineDiff.equals = function(left, right) {
if (this.options.ignoreWhitespace) {
// Special case handle for when one terminal is ignored (i.e. whitespace).
// For this case we merge the terminal into the prior string and drop the change.
// This is only available for string mode.
if (left === '') {
return Diff.prototype.equals.call(this, left, right.trim());
}
return Diff.prototype.equals.call(this, left.key, right.key);
}
return Diff.prototype.equals.call(this, left, right);
};

lineDiff.join = function(result) {
if (this.options.ignoreWhitespace) {
return result.map(v => v.payload).join('');
}
return result.join('');
};

export function diffLines(oldStr, newStr, callback) { return lineDiff.diff(oldStr, newStr, callback); }
export function diffTrimmedLines(oldStr, newStr, callback) {
let options = generateOptions(callback, {ignoreWhitespace: true});
Expand Down
41 changes: 38 additions & 3 deletions test/diff/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,52 @@ describe('diff/line', function() {
});

it('should ignore leading and trailing whitespace', function() {
const diffResult = diffTrimmedLines(
const diffResult1 = diffTrimmedLines(
'line\nvalue \nline',
'line\nvalue\nline');
expect(convertChangesToXML(diffResult)).to.equal('line\nvalue\nline');
expect(convertChangesToXML(diffResult1)).to.equal('line\nvalue\nline');

const diffResult2 = diffTrimmedLines(
'line\nvalue\nline',
'line\nvalue \nline');
expect(convertChangesToXML(diffResult2)).to.equal('line\nvalue \nline');

const diffResult3 = diffTrimmedLines(
'line\n value\nline',
'line\nvalue\nline');
expect(convertChangesToXML(diffResult3)).to.equal('line\nvalue\nline');

const diffResult4 = diffTrimmedLines(
'line\nvalue\nline',
'line\n value\nline');
expect(convertChangesToXML(diffResult4)).to.equal('line\n value\nline');
});

it('should keep leading and trailing whitespace in the output', function() {
function stringify(value) {
return JSON.stringify(value, null, 2);
}
const diffResult = diffTrimmedLines(
stringify([10, 20, 30]),
stringify({ data: [10, 42, 30] }));
expect(convertChangesToXML(diffResult)).to.equal([
'<del>[\n</del>',
'<ins>{\n',
' "data": [\n</ins>',
' 10,\n',
'<del> 20,\n</del>',
'<ins> 42,\n</ins>',
' 30\n',
'<del>]</del><ins> ]\n',
'}</ins>'
].join('').replace(/"/g, '&quot;'));
});

it('should handle windows line endings', function() {
const diffResult = diffTrimmedLines(
'line\r\nold value \r\nline',
'line\r\nnew value\r\nline');
expect(convertChangesToXML(diffResult)).to.equal('line\r\n<del>old value\r\n</del><ins>new value\r\n</ins>line');
expect(convertChangesToXML(diffResult)).to.equal('line\r\n<del>old value \r\n</del><ins>new value\r\n</ins>line');
});
});

Expand Down