diff --git a/src/editor/diff.js b/src/editor/diff.js index 2c82e22793..3b7b2aa79d 100644 --- a/src/editor/diff.js +++ b/src/editor/diff.js @@ -25,16 +25,6 @@ function firstDiff(a, b) { return compareLen; } -function lastDiff(a, b) { - const compareLen = Math.min(a.length, b.length); - for (let i = 0; i < compareLen; ++i) { - if (a[a.length - i] !== b[b.length - i]) { - return i; - } - } - return compareLen; -} - function diffStringsAtEnd(oldStr, newStr) { const len = Math.min(oldStr.length, newStr.length); const startInCommon = oldStr.substr(0, len) === newStr.substr(0, len); @@ -52,22 +42,14 @@ function diffStringsAtEnd(oldStr, newStr) { } } +// assumes only characters have been deleted at one location in the string, and none added export function diffDeletion(oldStr, newStr) { if (oldStr === newStr) { return {}; } const firstDiffIdx = firstDiff(oldStr, newStr); - const lastDiffIdx = oldStr.length - lastDiff(oldStr, newStr) + 1; - return {at: firstDiffIdx, removed: oldStr.substring(firstDiffIdx, lastDiffIdx)}; -} - -export function diffInsertion(oldStr, newStr) { - const diff = diffDeletion(newStr, oldStr); - if (diff.removed) { - return {at: diff.at, added: diff.removed}; - } else { - return diff; - } + const amount = oldStr.length - newStr.length; + return {at: firstDiffIdx, removed: oldStr.substr(firstDiffIdx, amount)}; } export function diffAtCaret(oldValue, newValue, caretPosition) { diff --git a/test/editor/diff-test.js b/test/editor/diff-test.js new file mode 100644 index 0000000000..257c35c22f --- /dev/null +++ b/test/editor/diff-test.js @@ -0,0 +1,48 @@ +/* +Copyright 2019 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import expect from 'expect'; +import {diffDeletion} from "../../src/editor/diff"; + +describe('editor/diff', function() { + describe('diffDeletion', function() { + it('at start of string', function() { + const diff = diffDeletion("hello", "ello"); + expect(diff.at).toBe(0); + expect(diff.removed).toBe("h"); + }); + it('removing whole string', function() { + const diff = diffDeletion("hello", ""); + expect(diff.at).toBe(0); + expect(diff.removed).toBe("hello"); + }); + it('in middle of string', function() { + const diff = diffDeletion("hello", "hllo"); + expect(diff.at).toBe(1); + expect(diff.removed).toBe("e"); + }); + it('in middle of string with duplicate character', function() { + const diff = diffDeletion("hello", "helo"); + expect(diff.at).toBe(3); + expect(diff.removed).toBe("l"); + }); + it('at end of string', function() { + const diff = diffDeletion("hello", "hell"); + expect(diff.at).toBe(4); + expect(diff.removed).toBe("o"); + }); + }); +});