Best JavaScript code snippet using jest-extended
diff_match_patch_test.py
Source:diff_match_patch_test.py
1#!/usr/bin/python32"""Test harness for diff_match_patch.py3Copyright 2006 Google Inc.4http://code.google.com/p/google-diff-match-patch/5Licensed under the Apache License, Version 2.0 (the "License");6you may not use this file except in compliance with the License.7You may obtain a copy of the License at8 http://www.apache.org/licenses/LICENSE-2.09Unless required by applicable law or agreed to in writing, software10distributed under the License is distributed on an "AS IS" BASIS,11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12See the License for the specific language governing permissions and13limitations under the License.14"""15import imp16import sys17import time18import unittest19import diff_match_patch as dmp_module20# Force a module reload. Allows one to edit the DMP module and rerun the tests21# without leaving the Python interpreter.22imp.reload(dmp_module)23class DiffMatchPatchTest(unittest.TestCase):24 def setUp(self):25 "Test harness for dmp_module."26 self.dmp = dmp_module.diff_match_patch()27 def diff_rebuildtexts(self, diffs):28 # Construct the two texts which made up the diff originally.29 text1 = ""30 text2 = ""31 for x in range(0, len(diffs)):32 if diffs[x][0] != dmp_module.diff_match_patch.DIFF_INSERT:33 text1 += diffs[x][1]34 if diffs[x][0] != dmp_module.diff_match_patch.DIFF_DELETE:35 text2 += diffs[x][1]36 return (text1, text2)37class DiffTest(DiffMatchPatchTest):38 """DIFF TEST FUNCTIONS"""39 def testDiffCommonPrefix(self):40 # Detect any common prefix.41 # Null case.42 self.assertEqual(0, self.dmp.diff_commonPrefix("abc", "xyz"))43 # Non-null case.44 self.assertEqual(4, self.dmp.diff_commonPrefix("1234abcdef", "1234xyz"))45 # Whole case.46 self.assertEqual(4, self.dmp.diff_commonPrefix("1234", "1234xyz"))47 def testDiffCommonSuffix(self):48 # Detect any common suffix.49 # Null case.50 self.assertEqual(0, self.dmp.diff_commonSuffix("abc", "xyz"))51 # Non-null case.52 self.assertEqual(4, self.dmp.diff_commonSuffix("abcdef1234", "xyz1234"))53 # Whole case.54 self.assertEqual(4, self.dmp.diff_commonSuffix("1234", "xyz1234"))55 def testDiffCommonOverlap(self):56 # Null case.57 self.assertEqual(0, self.dmp.diff_commonOverlap("", "abcd"))58 # Whole case.59 self.assertEqual(3, self.dmp.diff_commonOverlap("abc", "abcd"))60 # No overlap.61 self.assertEqual(0, self.dmp.diff_commonOverlap("123456", "abcd"))62 # Overlap.63 self.assertEqual(3, self.dmp.diff_commonOverlap("123456xxx", "xxxabcd"))64 # Unicode.65 # Some overly clever languages (C#) may treat ligatures as equal to their66 # component letters. E.g. U+FB01 == 'fi'67 self.assertEqual(0, self.dmp.diff_commonOverlap("fi", "\ufb01i"))68 def testDiffHalfMatch(self):69 # Detect a halfmatch.70 self.dmp.Diff_Timeout = 171 # No match.72 self.assertEqual(None, self.dmp.diff_halfMatch("1234567890", "abcdef"))73 self.assertEqual(None, self.dmp.diff_halfMatch("12345", "23"))74 # Single Match.75 self.assertEqual(("12", "90", "a", "z", "345678"), self.dmp.diff_halfMatch("1234567890", "a345678z"))76 self.assertEqual(("a", "z", "12", "90", "345678"), self.dmp.diff_halfMatch("a345678z", "1234567890"))77 self.assertEqual(("abc", "z", "1234", "0", "56789"), self.dmp.diff_halfMatch("abc56789z", "1234567890"))78 self.assertEqual(("a", "xyz", "1", "7890", "23456"), self.dmp.diff_halfMatch("a23456xyz", "1234567890"))79 # Multiple Matches.80 self.assertEqual(("12123", "123121", "a", "z", "1234123451234"), self.dmp.diff_halfMatch("121231234123451234123121", "a1234123451234z"))81 self.assertEqual(("", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="), self.dmp.diff_halfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-="))82 self.assertEqual(("-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"), self.dmp.diff_halfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy"))83 # Non-optimal halfmatch.84 # Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy85 self.assertEqual(("qHillo", "w", "x", "Hulloy", "HelloHe"), self.dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy"))86 # Optimal no halfmatch.87 self.dmp.Diff_Timeout = 088 self.assertEqual(None, self.dmp.diff_halfMatch("qHilloHelloHew", "xHelloHeHulloy"))89 def testDiffLinesToChars(self):90 # Convert lines down to characters.91 self.assertEqual(("\x01\x02\x01", "\x02\x01\x02", ["", "alpha\n", "beta\n"]), self.dmp.diff_linesToChars("alpha\nbeta\nalpha\n", "beta\nalpha\nbeta\n"))92 self.assertEqual(("", "\x01\x02\x03\x03", ["", "alpha\r\n", "beta\r\n", "\r\n"]), self.dmp.diff_linesToChars("", "alpha\r\nbeta\r\n\r\n\r\n"))93 self.assertEqual(("\x01", "\x02", ["", "a", "b"]), self.dmp.diff_linesToChars("a", "b"))94 # More than 256 to reveal any 8-bit limitations.95 n = 30096 lineList = []97 charList = []98 for x in range(1, n + 1):99 lineList.append(str(x) + "\n")100 charList.append(chr(x))101 self.assertEqual(n, len(lineList))102 lines = "".join(lineList)103 chars = "".join(charList)104 self.assertEqual(n, len(chars))105 lineList.insert(0, "")106 self.assertEqual((chars, "", lineList), self.dmp.diff_linesToChars(lines, ""))107 def testDiffCharsToLines(self):108 # Convert chars up to lines.109 diffs = [(self.dmp.DIFF_EQUAL, "\x01\x02\x01"), (self.dmp.DIFF_INSERT, "\x02\x01\x02")]110 self.dmp.diff_charsToLines(diffs, ["", "alpha\n", "beta\n"])111 self.assertEqual([(self.dmp.DIFF_EQUAL, "alpha\nbeta\nalpha\n"), (self.dmp.DIFF_INSERT, "beta\nalpha\nbeta\n")], diffs)112 # More than 256 to reveal any 8-bit limitations.113 n = 300114 lineList = []115 charList = []116 for x in range(1, n + 1):117 lineList.append(str(x) + "\n")118 charList.append(chr(x))119 self.assertEqual(n, len(lineList))120 lines = "".join(lineList)121 chars = "".join(charList)122 self.assertEqual(n, len(chars))123 lineList.insert(0, "")124 diffs = [(self.dmp.DIFF_DELETE, chars)]125 self.dmp.diff_charsToLines(diffs, lineList)126 self.assertEqual([(self.dmp.DIFF_DELETE, lines)], diffs)127 def testDiffCleanupMerge(self):128 # Cleanup a messy diff.129 # Null case.130 diffs = []131 self.dmp.diff_cleanupMerge(diffs)132 self.assertEqual([], diffs)133 # No change case.134 diffs = [(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "b"), (self.dmp.DIFF_INSERT, "c")]135 self.dmp.diff_cleanupMerge(diffs)136 self.assertEqual([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "b"), (self.dmp.DIFF_INSERT, "c")], diffs)137 # Merge equalities.138 diffs = [(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_EQUAL, "b"), (self.dmp.DIFF_EQUAL, "c")]139 self.dmp.diff_cleanupMerge(diffs)140 self.assertEqual([(self.dmp.DIFF_EQUAL, "abc")], diffs)141 # Merge deletions.142 diffs = [(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_DELETE, "b"), (self.dmp.DIFF_DELETE, "c")]143 self.dmp.diff_cleanupMerge(diffs)144 self.assertEqual([(self.dmp.DIFF_DELETE, "abc")], diffs)145 # Merge insertions.146 diffs = [(self.dmp.DIFF_INSERT, "a"), (self.dmp.DIFF_INSERT, "b"), (self.dmp.DIFF_INSERT, "c")]147 self.dmp.diff_cleanupMerge(diffs)148 self.assertEqual([(self.dmp.DIFF_INSERT, "abc")], diffs)149 # Merge interweave.150 diffs = [(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "b"), (self.dmp.DIFF_DELETE, "c"), (self.dmp.DIFF_INSERT, "d"), (self.dmp.DIFF_EQUAL, "e"), (self.dmp.DIFF_EQUAL, "f")]151 self.dmp.diff_cleanupMerge(diffs)152 self.assertEqual([(self.dmp.DIFF_DELETE, "ac"), (self.dmp.DIFF_INSERT, "bd"), (self.dmp.DIFF_EQUAL, "ef")], diffs)153 # Prefix and suffix detection.154 diffs = [(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "abc"), (self.dmp.DIFF_DELETE, "dc")]155 self.dmp.diff_cleanupMerge(diffs)156 self.assertEqual([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "d"), (self.dmp.DIFF_INSERT, "b"), (self.dmp.DIFF_EQUAL, "c")], diffs)157 # Prefix and suffix detection with equalities.158 diffs = [(self.dmp.DIFF_EQUAL, "x"), (self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "abc"), (self.dmp.DIFF_DELETE, "dc"), (self.dmp.DIFF_EQUAL, "y")]159 self.dmp.diff_cleanupMerge(diffs)160 self.assertEqual([(self.dmp.DIFF_EQUAL, "xa"), (self.dmp.DIFF_DELETE, "d"), (self.dmp.DIFF_INSERT, "b"), (self.dmp.DIFF_EQUAL, "cy")], diffs)161 # Slide edit left.162 diffs = [(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_INSERT, "ba"), (self.dmp.DIFF_EQUAL, "c")]163 self.dmp.diff_cleanupMerge(diffs)164 self.assertEqual([(self.dmp.DIFF_INSERT, "ab"), (self.dmp.DIFF_EQUAL, "ac")], diffs)165 # Slide edit right.166 diffs = [(self.dmp.DIFF_EQUAL, "c"), (self.dmp.DIFF_INSERT, "ab"), (self.dmp.DIFF_EQUAL, "a")]167 self.dmp.diff_cleanupMerge(diffs)168 self.assertEqual([(self.dmp.DIFF_EQUAL, "ca"), (self.dmp.DIFF_INSERT, "ba")], diffs)169 # Slide edit left recursive.170 diffs = [(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "b"), (self.dmp.DIFF_EQUAL, "c"), (self.dmp.DIFF_DELETE, "ac"), (self.dmp.DIFF_EQUAL, "x")]171 self.dmp.diff_cleanupMerge(diffs)172 self.assertEqual([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_EQUAL, "acx")], diffs)173 # Slide edit right recursive.174 diffs = [(self.dmp.DIFF_EQUAL, "x"), (self.dmp.DIFF_DELETE, "ca"), (self.dmp.DIFF_EQUAL, "c"), (self.dmp.DIFF_DELETE, "b"), (self.dmp.DIFF_EQUAL, "a")]175 self.dmp.diff_cleanupMerge(diffs)176 self.assertEqual([(self.dmp.DIFF_EQUAL, "xca"), (self.dmp.DIFF_DELETE, "cba")], diffs)177 def testDiffCleanupSemanticLossless(self):178 # Slide diffs to match logical boundaries.179 # Null case.180 diffs = []181 self.dmp.diff_cleanupSemanticLossless(diffs)182 self.assertEqual([], diffs)183 # Blank lines.184 diffs = [(self.dmp.DIFF_EQUAL, "AAA\r\n\r\nBBB"), (self.dmp.DIFF_INSERT, "\r\nDDD\r\n\r\nBBB"), (self.dmp.DIFF_EQUAL, "\r\nEEE")]185 self.dmp.diff_cleanupSemanticLossless(diffs)186 self.assertEqual([(self.dmp.DIFF_EQUAL, "AAA\r\n\r\n"), (self.dmp.DIFF_INSERT, "BBB\r\nDDD\r\n\r\n"), (self.dmp.DIFF_EQUAL, "BBB\r\nEEE")], diffs)187 # Line boundaries.188 diffs = [(self.dmp.DIFF_EQUAL, "AAA\r\nBBB"), (self.dmp.DIFF_INSERT, " DDD\r\nBBB"), (self.dmp.DIFF_EQUAL, " EEE")]189 self.dmp.diff_cleanupSemanticLossless(diffs)190 self.assertEqual([(self.dmp.DIFF_EQUAL, "AAA\r\n"), (self.dmp.DIFF_INSERT, "BBB DDD\r\n"), (self.dmp.DIFF_EQUAL, "BBB EEE")], diffs)191 # Word boundaries.192 diffs = [(self.dmp.DIFF_EQUAL, "The c"), (self.dmp.DIFF_INSERT, "ow and the c"), (self.dmp.DIFF_EQUAL, "at.")]193 self.dmp.diff_cleanupSemanticLossless(diffs)194 self.assertEqual([(self.dmp.DIFF_EQUAL, "The "), (self.dmp.DIFF_INSERT, "cow and the "), (self.dmp.DIFF_EQUAL, "cat.")], diffs)195 # Alphanumeric boundaries.196 diffs = [(self.dmp.DIFF_EQUAL, "The-c"), (self.dmp.DIFF_INSERT, "ow-and-the-c"), (self.dmp.DIFF_EQUAL, "at.")]197 self.dmp.diff_cleanupSemanticLossless(diffs)198 self.assertEqual([(self.dmp.DIFF_EQUAL, "The-"), (self.dmp.DIFF_INSERT, "cow-and-the-"), (self.dmp.DIFF_EQUAL, "cat.")], diffs)199 # Hitting the start.200 diffs = [(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_EQUAL, "ax")]201 self.dmp.diff_cleanupSemanticLossless(diffs)202 self.assertEqual([(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_EQUAL, "aax")], diffs)203 # Hitting the end.204 diffs = [(self.dmp.DIFF_EQUAL, "xa"), (self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_EQUAL, "a")]205 self.dmp.diff_cleanupSemanticLossless(diffs)206 self.assertEqual([(self.dmp.DIFF_EQUAL, "xaa"), (self.dmp.DIFF_DELETE, "a")], diffs)207 # Sentence boundaries.208 diffs = [(self.dmp.DIFF_EQUAL, "The xxx. The "), (self.dmp.DIFF_INSERT, "zzz. The "), (self.dmp.DIFF_EQUAL, "yyy.")]209 self.dmp.diff_cleanupSemanticLossless(diffs)210 self.assertEqual([(self.dmp.DIFF_EQUAL, "The xxx."), (self.dmp.DIFF_INSERT, " The zzz."), (self.dmp.DIFF_EQUAL, " The yyy.")], diffs)211 def testDiffCleanupSemantic(self):212 # Cleanup semantically trivial equalities.213 # Null case.214 diffs = []215 self.dmp.diff_cleanupSemantic(diffs)216 self.assertEqual([], diffs)217 # No elimination #1.218 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "cd"), (self.dmp.DIFF_EQUAL, "12"), (self.dmp.DIFF_DELETE, "e")]219 self.dmp.diff_cleanupSemantic(diffs)220 self.assertEqual([(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "cd"), (self.dmp.DIFF_EQUAL, "12"), (self.dmp.DIFF_DELETE, "e")], diffs)221 # No elimination #2.222 diffs = [(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_INSERT, "ABC"), (self.dmp.DIFF_EQUAL, "1234"), (self.dmp.DIFF_DELETE, "wxyz")]223 self.dmp.diff_cleanupSemantic(diffs)224 self.assertEqual([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_INSERT, "ABC"), (self.dmp.DIFF_EQUAL, "1234"), (self.dmp.DIFF_DELETE, "wxyz")], diffs)225 # Simple elimination.226 diffs = [(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_EQUAL, "b"), (self.dmp.DIFF_DELETE, "c")]227 self.dmp.diff_cleanupSemantic(diffs)228 self.assertEqual([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_INSERT, "b")], diffs)229 # Backpass elimination.230 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_EQUAL, "cd"), (self.dmp.DIFF_DELETE, "e"), (self.dmp.DIFF_EQUAL, "f"), (self.dmp.DIFF_INSERT, "g")]231 self.dmp.diff_cleanupSemantic(diffs)232 self.assertEqual([(self.dmp.DIFF_DELETE, "abcdef"), (self.dmp.DIFF_INSERT, "cdfg")], diffs)233 # Multiple eliminations.234 diffs = [(self.dmp.DIFF_INSERT, "1"), (self.dmp.DIFF_EQUAL, "A"), (self.dmp.DIFF_DELETE, "B"), (self.dmp.DIFF_INSERT, "2"), (self.dmp.DIFF_EQUAL, "_"), (self.dmp.DIFF_INSERT, "1"), (self.dmp.DIFF_EQUAL, "A"), (self.dmp.DIFF_DELETE, "B"), (self.dmp.DIFF_INSERT, "2")]235 self.dmp.diff_cleanupSemantic(diffs)236 self.assertEqual([(self.dmp.DIFF_DELETE, "AB_AB"), (self.dmp.DIFF_INSERT, "1A2_1A2")], diffs)237 # Word boundaries.238 diffs = [(self.dmp.DIFF_EQUAL, "The c"), (self.dmp.DIFF_DELETE, "ow and the c"), (self.dmp.DIFF_EQUAL, "at.")]239 self.dmp.diff_cleanupSemantic(diffs)240 self.assertEqual([(self.dmp.DIFF_EQUAL, "The "), (self.dmp.DIFF_DELETE, "cow and the "), (self.dmp.DIFF_EQUAL, "cat.")], diffs)241 # No overlap elimination.242 diffs = [(self.dmp.DIFF_DELETE, "abcxx"), (self.dmp.DIFF_INSERT, "xxdef")]243 self.dmp.diff_cleanupSemantic(diffs)244 self.assertEqual([(self.dmp.DIFF_DELETE, "abcxx"), (self.dmp.DIFF_INSERT, "xxdef")], diffs)245 # Overlap elimination.246 diffs = [(self.dmp.DIFF_DELETE, "abcxxx"), (self.dmp.DIFF_INSERT, "xxxdef")]247 self.dmp.diff_cleanupSemantic(diffs)248 self.assertEqual([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_EQUAL, "xxx"), (self.dmp.DIFF_INSERT, "def")], diffs)249 # Reverse overlap elimination.250 diffs = [(self.dmp.DIFF_DELETE, "xxxabc"), (self.dmp.DIFF_INSERT, "defxxx")]251 self.dmp.diff_cleanupSemantic(diffs)252 self.assertEqual([(self.dmp.DIFF_INSERT, "def"), (self.dmp.DIFF_EQUAL, "xxx"), (self.dmp.DIFF_DELETE, "abc")], diffs)253 # Two overlap eliminations.254 diffs = [(self.dmp.DIFF_DELETE, "abcd1212"), (self.dmp.DIFF_INSERT, "1212efghi"), (self.dmp.DIFF_EQUAL, "----"), (self.dmp.DIFF_DELETE, "A3"), (self.dmp.DIFF_INSERT, "3BC")]255 self.dmp.diff_cleanupSemantic(diffs)256 self.assertEqual([(self.dmp.DIFF_DELETE, "abcd"), (self.dmp.DIFF_EQUAL, "1212"), (self.dmp.DIFF_INSERT, "efghi"), (self.dmp.DIFF_EQUAL, "----"), (self.dmp.DIFF_DELETE, "A"), (self.dmp.DIFF_EQUAL, "3"), (self.dmp.DIFF_INSERT, "BC")], diffs)257 def testDiffCleanupEfficiency(self):258 # Cleanup operationally trivial equalities.259 self.dmp.Diff_EditCost = 4260 # Null case.261 diffs = []262 self.dmp.diff_cleanupEfficiency(diffs)263 self.assertEqual([], diffs)264 # No elimination.265 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "wxyz"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "34")]266 self.dmp.diff_cleanupEfficiency(diffs)267 self.assertEqual([(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "wxyz"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "34")], diffs)268 # Four-edit elimination.269 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "xyz"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "34")]270 self.dmp.diff_cleanupEfficiency(diffs)271 self.assertEqual([(self.dmp.DIFF_DELETE, "abxyzcd"), (self.dmp.DIFF_INSERT, "12xyz34")], diffs)272 # Three-edit elimination.273 diffs = [(self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "x"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "34")]274 self.dmp.diff_cleanupEfficiency(diffs)275 self.assertEqual([(self.dmp.DIFF_DELETE, "xcd"), (self.dmp.DIFF_INSERT, "12x34")], diffs)276 # Backpass elimination.277 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "xy"), (self.dmp.DIFF_INSERT, "34"), (self.dmp.DIFF_EQUAL, "z"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "56")]278 self.dmp.diff_cleanupEfficiency(diffs)279 self.assertEqual([(self.dmp.DIFF_DELETE, "abxyzcd"), (self.dmp.DIFF_INSERT, "12xy34z56")], diffs)280 # High cost elimination.281 self.dmp.Diff_EditCost = 5282 diffs = [(self.dmp.DIFF_DELETE, "ab"), (self.dmp.DIFF_INSERT, "12"), (self.dmp.DIFF_EQUAL, "wxyz"), (self.dmp.DIFF_DELETE, "cd"), (self.dmp.DIFF_INSERT, "34")]283 self.dmp.diff_cleanupEfficiency(diffs)284 self.assertEqual([(self.dmp.DIFF_DELETE, "abwxyzcd"), (self.dmp.DIFF_INSERT, "12wxyz34")], diffs)285 self.dmp.Diff_EditCost = 4286 def testDiffPrettyHtml(self):287 # Pretty print.288 diffs = [(self.dmp.DIFF_EQUAL, "a\n"), (self.dmp.DIFF_DELETE, "<B>b</B>"), (self.dmp.DIFF_INSERT, "c&d")]289 self.assertEqual("<span>a¶<br></span><del style=\"background:#ffe6e6;\"><B>b</B></del><ins style=\"background:#e6ffe6;\">c&d</ins>", self.dmp.diff_prettyHtml(diffs))290 def testDiffText(self):291 # Compute the source and destination texts.292 diffs = [(self.dmp.DIFF_EQUAL, "jump"), (self.dmp.DIFF_DELETE, "s"), (self.dmp.DIFF_INSERT, "ed"), (self.dmp.DIFF_EQUAL, " over "), (self.dmp.DIFF_DELETE, "the"), (self.dmp.DIFF_INSERT, "a"), (self.dmp.DIFF_EQUAL, " lazy")]293 self.assertEqual("jumps over the lazy", self.dmp.diff_text1(diffs))294 self.assertEqual("jumped over a lazy", self.dmp.diff_text2(diffs))295 def testDiffDelta(self):296 # Convert a diff into delta string.297 diffs = [(self.dmp.DIFF_EQUAL, "jump"), (self.dmp.DIFF_DELETE, "s"), (self.dmp.DIFF_INSERT, "ed"), (self.dmp.DIFF_EQUAL, " over "), (self.dmp.DIFF_DELETE, "the"), (self.dmp.DIFF_INSERT, "a"), (self.dmp.DIFF_EQUAL, " lazy"), (self.dmp.DIFF_INSERT, "old dog")]298 text1 = self.dmp.diff_text1(diffs)299 self.assertEqual("jumps over the lazy", text1)300 delta = self.dmp.diff_toDelta(diffs)301 self.assertEqual("=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", delta)302 # Convert delta string into a diff.303 self.assertEqual(diffs, self.dmp.diff_fromDelta(text1, delta))304 # Generates error (19 != 20).305 try:306 self.dmp.diff_fromDelta(text1 + "x", delta)307 self.assertFalse(True)308 except ValueError:309 # Exception expected.310 pass311 # Generates error (19 != 18).312 try:313 self.dmp.diff_fromDelta(text1[1:], delta)314 self.assertFalse(True)315 except ValueError:316 # Exception expected.317 pass318 # Generates error (%c3%xy invalid Unicode).319 # Note: Python 3 can decode this.320 #try:321 # self.dmp.diff_fromDelta("", "+%c3xy")322 # self.assertFalse(True)323 #except ValueError:324 # # Exception expected.325 # pass326 # Test deltas with special characters.327 diffs = [(self.dmp.DIFF_EQUAL, "\u0680 \x00 \t %"), (self.dmp.DIFF_DELETE, "\u0681 \x01 \n ^"), (self.dmp.DIFF_INSERT, "\u0682 \x02 \\ |")]328 text1 = self.dmp.diff_text1(diffs)329 self.assertEqual("\u0680 \x00 \t %\u0681 \x01 \n ^", text1)330 delta = self.dmp.diff_toDelta(diffs)331 self.assertEqual("=7\t-7\t+%DA%82 %02 %5C %7C", delta)332 # Convert delta string into a diff.333 self.assertEqual(diffs, self.dmp.diff_fromDelta(text1, delta))334 # Verify pool of unchanged characters.335 diffs = [(self.dmp.DIFF_INSERT, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ")]336 text2 = self.dmp.diff_text2(diffs)337 self.assertEqual("A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", text2)338 delta = self.dmp.diff_toDelta(diffs)339 self.assertEqual("+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ", delta)340 # Convert delta string into a diff.341 self.assertEqual(diffs, self.dmp.diff_fromDelta("", delta))342 def testDiffXIndex(self):343 # Translate a location in text1 to text2.344 self.assertEqual(5, self.dmp.diff_xIndex([(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "1234"), (self.dmp.DIFF_EQUAL, "xyz")], 2))345 # Translation on deletion.346 self.assertEqual(1, self.dmp.diff_xIndex([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "1234"), (self.dmp.DIFF_EQUAL, "xyz")], 3))347 def testDiffLevenshtein(self):348 # Levenshtein with trailing equality.349 self.assertEqual(4, self.dmp.diff_levenshtein([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_INSERT, "1234"), (self.dmp.DIFF_EQUAL, "xyz")]))350 # Levenshtein with leading equality.351 self.assertEqual(4, self.dmp.diff_levenshtein([(self.dmp.DIFF_EQUAL, "xyz"), (self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_INSERT, "1234")]))352 # Levenshtein with middle equality.353 self.assertEqual(7, self.dmp.diff_levenshtein([(self.dmp.DIFF_DELETE, "abc"), (self.dmp.DIFF_EQUAL, "xyz"), (self.dmp.DIFF_INSERT, "1234")]))354 def testDiffBisect(self):355 # Normal.356 a = "cat"357 b = "map"358 # Since the resulting diff hasn't been normalized, it would be ok if359 # the insertion and deletion pairs are swapped.360 # If the order changes, tweak this test as required.361 self.assertEqual([(self.dmp.DIFF_DELETE, "c"), (self.dmp.DIFF_INSERT, "m"), (self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "t"), (self.dmp.DIFF_INSERT, "p")], self.dmp.diff_bisect(a, b, sys.maxsize))362 # Timeout.363 self.assertEqual([(self.dmp.DIFF_DELETE, "cat"), (self.dmp.DIFF_INSERT, "map")], self.dmp.diff_bisect(a, b, 0))364 def testDiffMain(self):365 # Perform a trivial diff.366 # Null case.367 self.assertEqual([], self.dmp.diff_main("", "", False))368 # Equality.369 self.assertEqual([(self.dmp.DIFF_EQUAL, "abc")], self.dmp.diff_main("abc", "abc", False))370 # Simple insertion.371 self.assertEqual([(self.dmp.DIFF_EQUAL, "ab"), (self.dmp.DIFF_INSERT, "123"), (self.dmp.DIFF_EQUAL, "c")], self.dmp.diff_main("abc", "ab123c", False))372 # Simple deletion.373 self.assertEqual([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "123"), (self.dmp.DIFF_EQUAL, "bc")], self.dmp.diff_main("a123bc", "abc", False))374 # Two insertions.375 self.assertEqual([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_INSERT, "123"), (self.dmp.DIFF_EQUAL, "b"), (self.dmp.DIFF_INSERT, "456"), (self.dmp.DIFF_EQUAL, "c")], self.dmp.diff_main("abc", "a123b456c", False))376 # Two deletions.377 self.assertEqual([(self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "123"), (self.dmp.DIFF_EQUAL, "b"), (self.dmp.DIFF_DELETE, "456"), (self.dmp.DIFF_EQUAL, "c")], self.dmp.diff_main("a123b456c", "abc", False))378 # Perform a real diff.379 # Switch off the timeout.380 self.dmp.Diff_Timeout = 0381 # Simple cases.382 self.assertEqual([(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "b")], self.dmp.diff_main("a", "b", False))383 self.assertEqual([(self.dmp.DIFF_DELETE, "Apple"), (self.dmp.DIFF_INSERT, "Banana"), (self.dmp.DIFF_EQUAL, "s are a"), (self.dmp.DIFF_INSERT, "lso"), (self.dmp.DIFF_EQUAL, " fruit.")], self.dmp.diff_main("Apples are a fruit.", "Bananas are also fruit.", False))384 self.assertEqual([(self.dmp.DIFF_DELETE, "a"), (self.dmp.DIFF_INSERT, "\u0680"), (self.dmp.DIFF_EQUAL, "x"), (self.dmp.DIFF_DELETE, "\t"), (self.dmp.DIFF_INSERT, "\x00")], self.dmp.diff_main("ax\t", "\u0680x\x00", False))385 # Overlaps.386 self.assertEqual([(self.dmp.DIFF_DELETE, "1"), (self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "y"), (self.dmp.DIFF_EQUAL, "b"), (self.dmp.DIFF_DELETE, "2"), (self.dmp.DIFF_INSERT, "xab")], self.dmp.diff_main("1ayb2", "abxab", False))387 self.assertEqual([(self.dmp.DIFF_INSERT, "xaxcx"), (self.dmp.DIFF_EQUAL, "abc"), (self.dmp.DIFF_DELETE, "y")], self.dmp.diff_main("abcy", "xaxcxabc", False))388 self.assertEqual([(self.dmp.DIFF_DELETE, "ABCD"), (self.dmp.DIFF_EQUAL, "a"), (self.dmp.DIFF_DELETE, "="), (self.dmp.DIFF_INSERT, "-"), (self.dmp.DIFF_EQUAL, "bcd"), (self.dmp.DIFF_DELETE, "="), (self.dmp.DIFF_INSERT, "-"), (self.dmp.DIFF_EQUAL, "efghijklmnopqrs"), (self.dmp.DIFF_DELETE, "EFGHIJKLMNOefg")], self.dmp.diff_main("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", False))389 # Large equality.390 self.assertEqual([(self.dmp.DIFF_INSERT, " "), (self.dmp.DIFF_EQUAL,"a"), (self.dmp.DIFF_INSERT,"nd"), (self.dmp.DIFF_EQUAL," [[Pennsylvania]]"), (self.dmp.DIFF_DELETE," and [[New")], self.dmp.diff_main("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", False))391 # Timeout.392 self.dmp.Diff_Timeout = 0.1 # 100ms393 a = "`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n"394 b = "I am the very model of a modern major general,\nI've information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n"395 # Increase the text lengths by 1024 times to ensure a timeout.396 for x in range(10):397 a = a + a398 b = b + b399 startTime = time.time()400 self.dmp.diff_main(a, b)401 endTime = time.time()402 # Test that we took at least the timeout period.403 self.assertTrue(self.dmp.Diff_Timeout <= endTime - startTime)404 # Test that we didn't take forever (be forgiving).405 # Theoretically this test could fail very occasionally if the406 # OS task swaps or locks up for a second at the wrong moment.407 self.assertTrue(self.dmp.Diff_Timeout * 2 > endTime - startTime)408 self.dmp.Diff_Timeout = 0409 # Test the linemode speedup.410 # Must be long to pass the 100 char cutoff.411 # Simple line-mode.412 a = "1234567890\n" * 13413 b = "abcdefghij\n" * 13414 self.assertEqual(self.dmp.diff_main(a, b, False), self.dmp.diff_main(a, b, True))415 # Single line-mode.416 a = "1234567890" * 13417 b = "abcdefghij" * 13418 self.assertEqual(self.dmp.diff_main(a, b, False), self.dmp.diff_main(a, b, True))419 # Overlap line-mode.420 a = "1234567890\n" * 13421 b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"422 texts_linemode = self.diff_rebuildtexts(self.dmp.diff_main(a, b, True))423 texts_textmode = self.diff_rebuildtexts(self.dmp.diff_main(a, b, False))424 self.assertEqual(texts_textmode, texts_linemode)425 # Test null inputs.426 try:427 self.dmp.diff_main(None, None)428 self.assertFalse(True)429 except ValueError:430 # Exception expected.431 pass432class MatchTest(DiffMatchPatchTest):433 """MATCH TEST FUNCTIONS"""434 def testMatchAlphabet(self):435 # Initialise the bitmasks for Bitap.436 self.assertEqual({"a":4, "b":2, "c":1}, self.dmp.match_alphabet("abc"))437 self.assertEqual({"a":37, "b":18, "c":8}, self.dmp.match_alphabet("abcaba"))438 def testMatchBitap(self):439 self.dmp.Match_Distance = 100440 self.dmp.Match_Threshold = 0.5441 # Exact matches.442 self.assertEqual(5, self.dmp.match_bitap("abcdefghijk", "fgh", 5))443 self.assertEqual(5, self.dmp.match_bitap("abcdefghijk", "fgh", 0))444 # Fuzzy matches.445 self.assertEqual(4, self.dmp.match_bitap("abcdefghijk", "efxhi", 0))446 self.assertEqual(2, self.dmp.match_bitap("abcdefghijk", "cdefxyhijk", 5))447 self.assertEqual(-1, self.dmp.match_bitap("abcdefghijk", "bxy", 1))448 # Overflow.449 self.assertEqual(2, self.dmp.match_bitap("123456789xx0", "3456789x0", 2))450 self.assertEqual(0, self.dmp.match_bitap("abcdef", "xxabc", 4))451 self.assertEqual(3, self.dmp.match_bitap("abcdef", "defyy", 4))452 self.assertEqual(0, self.dmp.match_bitap("abcdef", "xabcdefy", 0))453 # Threshold test.454 self.dmp.Match_Threshold = 0.4455 self.assertEqual(4, self.dmp.match_bitap("abcdefghijk", "efxyhi", 1))456 self.dmp.Match_Threshold = 0.3457 self.assertEqual(-1, self.dmp.match_bitap("abcdefghijk", "efxyhi", 1))458 self.dmp.Match_Threshold = 0.0459 self.assertEqual(1, self.dmp.match_bitap("abcdefghijk", "bcdef", 1))460 self.dmp.Match_Threshold = 0.5461 # Multiple select.462 self.assertEqual(0, self.dmp.match_bitap("abcdexyzabcde", "abccde", 3))463 self.assertEqual(8, self.dmp.match_bitap("abcdexyzabcde", "abccde", 5))464 # Distance test.465 self.dmp.Match_Distance = 10 # Strict location.466 self.assertEqual(-1, self.dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24))467 self.assertEqual(0, self.dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1))468 self.dmp.Match_Distance = 1000 # Loose location.469 self.assertEqual(0, self.dmp.match_bitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24))470 def testMatchMain(self):471 # Full match.472 # Shortcut matches.473 self.assertEqual(0, self.dmp.match_main("abcdef", "abcdef", 1000))474 self.assertEqual(-1, self.dmp.match_main("", "abcdef", 1))475 self.assertEqual(3, self.dmp.match_main("abcdef", "", 3))476 self.assertEqual(3, self.dmp.match_main("abcdef", "de", 3))477 self.assertEqual(3, self.dmp.match_main("abcdef", "defy", 4))478 self.assertEqual(0, self.dmp.match_main("abcdef", "abcdefy", 0))479 # Complex match.480 self.dmp.Match_Threshold = 0.7481 self.assertEqual(4, self.dmp.match_main("I am the very model of a modern major general.", " that berry ", 5))482 self.dmp.Match_Threshold = 0.5483 # Test null inputs.484 try:485 self.dmp.match_main(None, None, 0)486 self.assertFalse(True)487 except ValueError:488 # Exception expected.489 pass490class PatchTest(DiffMatchPatchTest):491 """PATCH TEST FUNCTIONS"""492 def testPatchObj(self):493 # Patch Object.494 p = dmp_module.patch_obj()495 p.start1 = 20496 p.start2 = 21497 p.length1 = 18498 p.length2 = 17499 p.diffs = [(self.dmp.DIFF_EQUAL, "jump"), (self.dmp.DIFF_DELETE, "s"), (self.dmp.DIFF_INSERT, "ed"), (self.dmp.DIFF_EQUAL, " over "), (self.dmp.DIFF_DELETE, "the"), (self.dmp.DIFF_INSERT, "a"), (self.dmp.DIFF_EQUAL, "\nlaz")]500 strp = str(p)501 self.assertEqual("@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n", strp)502 def testPatchFromText(self):503 self.assertEqual([], self.dmp.patch_fromText(""))504 strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n"505 self.assertEqual(strp, str(self.dmp.patch_fromText(strp)[0]))506 self.assertEqual("@@ -1 +1 @@\n-a\n+b\n", str(self.dmp.patch_fromText("@@ -1 +1 @@\n-a\n+b\n")[0]))507 self.assertEqual("@@ -1,3 +0,0 @@\n-abc\n", str(self.dmp.patch_fromText("@@ -1,3 +0,0 @@\n-abc\n")[0]))508 self.assertEqual("@@ -0,0 +1,3 @@\n+abc\n", str(self.dmp.patch_fromText("@@ -0,0 +1,3 @@\n+abc\n")[0]))509 # Generates error.510 try:511 self.dmp.patch_fromText("Bad\nPatch\n")512 self.assertFalse(True)513 except ValueError:514 # Exception expected.515 pass516 def testPatchToText(self):517 strp = "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"518 p = self.dmp.patch_fromText(strp)519 self.assertEqual(strp, self.dmp.patch_toText(p))520 strp = "@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n"521 p = self.dmp.patch_fromText(strp)522 self.assertEqual(strp, self.dmp.patch_toText(p))523 def testPatchAddContext(self):524 self.dmp.Patch_Margin = 4525 p = self.dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n")[0]526 self.dmp.patch_addContext(p, "The quick brown fox jumps over the lazy dog.")527 self.assertEqual("@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n", str(p))528 # Same, but not enough trailing context.529 p = self.dmp.patch_fromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n")[0]530 self.dmp.patch_addContext(p, "The quick brown fox jumps.")531 self.assertEqual("@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n", str(p))532 # Same, but not enough leading context.533 p = self.dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n")[0]534 self.dmp.patch_addContext(p, "The quick brown fox jumps.")535 self.assertEqual("@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n", str(p))536 # Same, but with ambiguity.537 p = self.dmp.patch_fromText("@@ -3 +3,2 @@\n-e\n+at\n")[0]538 self.dmp.patch_addContext(p, "The quick brown fox jumps. The quick brown fox crashes.")539 self.assertEqual("@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n", str(p))540 def testPatchMake(self):541 # Null case.542 patches = self.dmp.patch_make("", "")543 self.assertEqual("", self.dmp.patch_toText(patches))544 text1 = "The quick brown fox jumps over the lazy dog."545 text2 = "That quick brown fox jumped over a lazy dog."546 # Text2+Text1 inputs.547 expectedPatch = "@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n"548 # The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.549 patches = self.dmp.patch_make(text2, text1)550 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))551 # Text1+Text2 inputs.552 expectedPatch = "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n"553 patches = self.dmp.patch_make(text1, text2)554 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))555 # Diff input.556 diffs = self.dmp.diff_main(text1, text2, False)557 patches = self.dmp.patch_make(diffs)558 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))559 # Text1+Diff inputs.560 patches = self.dmp.patch_make(text1, diffs)561 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))562 # Text1+Text2+Diff inputs (deprecated).563 patches = self.dmp.patch_make(text1, text2, diffs)564 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))565 # Character encoding.566 patches = self.dmp.patch_make("`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?")567 self.assertEqual("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n", self.dmp.patch_toText(patches))568 # Character decoding.569 diffs = [(self.dmp.DIFF_DELETE, "`1234567890-=[]\\;',./"), (self.dmp.DIFF_INSERT, "~!@#$%^&*()_+{}|:\"<>?")]570 self.assertEqual(diffs, self.dmp.patch_fromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n")[0].diffs)571 # Long string with repeats.572 text1 = ""573 for x in range(100):574 text1 += "abcdef"575 text2 = text1 + "123"576 expectedPatch = "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"577 patches = self.dmp.patch_make(text1, text2)578 self.assertEqual(expectedPatch, self.dmp.patch_toText(patches))579 # Test null inputs.580 try:581 self.dmp.patch_make(None, None)582 self.assertFalse(True)583 except ValueError:584 # Exception expected.585 pass586 def testPatchSplitMax(self):587 # Assumes that Match_MaxBits is 32.588 patches = self.dmp.patch_make("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0")589 self.dmp.patch_splitMax(patches)590 self.assertEqual("@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n", self.dmp.patch_toText(patches))591 patches = self.dmp.patch_make("abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz")592 oldToText = self.dmp.patch_toText(patches)593 self.dmp.patch_splitMax(patches)594 self.assertEqual(oldToText, self.dmp.patch_toText(patches))595 patches = self.dmp.patch_make("1234567890123456789012345678901234567890123456789012345678901234567890", "abc")596 self.dmp.patch_splitMax(patches)597 self.assertEqual("@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n", self.dmp.patch_toText(patches))598 patches = self.dmp.patch_make("abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1", "abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1")599 self.dmp.patch_splitMax(patches)600 self.assertEqual("@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n", self.dmp.patch_toText(patches))601 def testPatchAddPadding(self):602 # Both edges full.603 patches = self.dmp.patch_make("", "test")604 self.assertEqual("@@ -0,0 +1,4 @@\n+test\n", self.dmp.patch_toText(patches))605 self.dmp.patch_addPadding(patches)606 self.assertEqual("@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n", self.dmp.patch_toText(patches))607 # Both edges partial.608 patches = self.dmp.patch_make("XY", "XtestY")609 self.assertEqual("@@ -1,2 +1,6 @@\n X\n+test\n Y\n", self.dmp.patch_toText(patches))610 self.dmp.patch_addPadding(patches)611 self.assertEqual("@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n", self.dmp.patch_toText(patches))612 # Both edges none.613 patches = self.dmp.patch_make("XXXXYYYY", "XXXXtestYYYY")614 self.assertEqual("@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n", self.dmp.patch_toText(patches))615 self.dmp.patch_addPadding(patches)616 self.assertEqual("@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n", self.dmp.patch_toText(patches))617 def testPatchApply(self):618 self.dmp.Match_Distance = 1000619 self.dmp.Match_Threshold = 0.5620 self.dmp.Patch_DeleteThreshold = 0.5621 # Null case.622 patches = self.dmp.patch_make("", "")623 results = self.dmp.patch_apply(patches, "Hello world.")624 self.assertEqual(("Hello world.", []), results)625 # Exact match.626 patches = self.dmp.patch_make("The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.")627 results = self.dmp.patch_apply(patches, "The quick brown fox jumps over the lazy dog.")628 self.assertEqual(("That quick brown fox jumped over a lazy dog.", [True, True]), results)629 # Partial match.630 results = self.dmp.patch_apply(patches, "The quick red rabbit jumps over the tired tiger.")631 self.assertEqual(("That quick red rabbit jumped over a tired tiger.", [True, True]), results)632 # Failed match.633 results = self.dmp.patch_apply(patches, "I am the very model of a modern major general.")634 self.assertEqual(("I am the very model of a modern major general.", [False, False]), results)635 # Big delete, small change.636 patches = self.dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")637 results = self.dmp.patch_apply(patches, "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y")638 self.assertEqual(("xabcy", [True, True]), results)639 # Big delete, big change 1.640 patches = self.dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")641 results = self.dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y")642 self.assertEqual(("xabc12345678901234567890---------------++++++++++---------------12345678901234567890y", [False, True]), results)643 # Big delete, big change 2.644 self.dmp.Patch_DeleteThreshold = 0.6645 patches = self.dmp.patch_make("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")646 results = self.dmp.patch_apply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y")647 self.assertEqual(("xabcy", [True, True]), results)648 self.dmp.Patch_DeleteThreshold = 0.5649 # Compensate for failed patch.650 self.dmp.Match_Threshold = 0.0651 self.dmp.Match_Distance = 0652 patches = self.dmp.patch_make("abcdefghijklmnopqrstuvwxyz--------------------1234567890", "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890")653 results = self.dmp.patch_apply(patches, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890")654 self.assertEqual(("ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890", [False, True]), results)655 self.dmp.Match_Threshold = 0.5656 self.dmp.Match_Distance = 1000657 # No side effects.658 patches = self.dmp.patch_make("", "test")659 patchstr = self.dmp.patch_toText(patches)660 results = self.dmp.patch_apply(patches, "")661 self.assertEqual(patchstr, self.dmp.patch_toText(patches))662 # No side effects with major delete.663 patches = self.dmp.patch_make("The quick brown fox jumps over the lazy dog.", "Woof")664 patchstr = self.dmp.patch_toText(patches)665 self.dmp.patch_apply(patches, "The quick brown fox jumps over the lazy dog.")666 self.assertEqual(patchstr, self.dmp.patch_toText(patches))667 # Edge exact match.668 patches = self.dmp.patch_make("", "test")669 self.dmp.patch_apply(patches, "")670 self.assertEqual(("test", [True]), results)671 # Near edge exact match.672 patches = self.dmp.patch_make("XY", "XtestY")673 results = self.dmp.patch_apply(patches, "XY")674 self.assertEqual(("XtestY", [True]), results)675 # Edge partial match.676 patches = self.dmp.patch_make("y", "y123")677 results = self.dmp.patch_apply(patches, "x")678 self.assertEqual(("x123", [True]), results)679if __name__ == "__main__":...
diff_match_patch_test.js
Source:diff_match_patch_test.js
1/**2 * Test Harness for Diff Match and Patch3 *4 * Copyright 2006 Google Inc.5 * http://code.google.com/p/google-diff-match-patch/6 *7 * Licensed under the Apache License, Version 2.0 (the "License");8 * you may not use this file except in compliance with the License.9 * You may obtain a copy of the License at10 *11 * http://www.apache.org/licenses/LICENSE-2.012 *13 * Unless required by applicable law or agreed to in writing, software14 * distributed under the License is distributed on an "AS IS" BASIS,15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.16 * See the License for the specific language governing permissions and17 * limitations under the License.18 */19// If expected and actual are the equivalent, pass the test.20function assertEquivalent(msg, expected, actual) {21 if (typeof actual == 'undefined') {22 // msg is optional.23 actual = expected;24 expected = msg;25 msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'';26 }27 if (_equivalent(expected, actual)) {28 assertEquals(msg, String.toString(expected), String.toString(actual));29 } else {30 assertEquals(msg, expected, actual);31 }32}33// Are a and b the equivalent? -- Recursive.34function _equivalent(a, b) {35 if (a == b) {36 return true;37 }38 if (typeof a == 'object' && typeof b == 'object' && a !== null && b !== null) {39 if (a.toString() != b.toString()) {40 return false;41 }42 for (var p in a) {43 if (!_equivalent(a[p], b[p])) {44 return false;45 }46 }47 for (var p in b) {48 if (!_equivalent(a[p], b[p])) {49 return false;50 }51 }52 return true;53 }54 return false;55}56function diff_rebuildtexts(diffs) {57 // Construct the two texts which made up the diff originally.58 var text1 = '';59 var text2 = '';60 for (var x = 0; x < diffs.length; x++) {61 if (diffs[x][0] != DIFF_INSERT) {62 text1 += diffs[x][1];63 }64 if (diffs[x][0] != DIFF_DELETE) {65 text2 += diffs[x][1];66 }67 }68 return [text1, text2];69}70var dmp = new diff_match_patch();71// DIFF TEST FUNCTIONS72function testDiffCommonPrefix() {73 // Detect any common prefix.74 // Null case.75 assertEquals(0, dmp.diff_commonPrefix('abc', 'xyz'));76 // Non-null case.77 assertEquals(4, dmp.diff_commonPrefix('1234abcdef', '1234xyz'));78 // Whole case.79 assertEquals(4, dmp.diff_commonPrefix('1234', '1234xyz'));80}81function testDiffCommonSuffix() {82 // Detect any common suffix.83 // Null case.84 assertEquals(0, dmp.diff_commonSuffix('abc', 'xyz'));85 // Non-null case.86 assertEquals(4, dmp.diff_commonSuffix('abcdef1234', 'xyz1234'));87 // Whole case.88 assertEquals(4, dmp.diff_commonSuffix('1234', 'xyz1234'));89}90function testDiffCommonOverlap() {91 // Detect any suffix/prefix overlap.92 // Null case.93 assertEquals(0, dmp.diff_commonOverlap_('', 'abcd'));94 // Whole case.95 assertEquals(3, dmp.diff_commonOverlap_('abc', 'abcd'));96 // No overlap.97 assertEquals(0, dmp.diff_commonOverlap_('123456', 'abcd'));98 // Overlap.99 assertEquals(3, dmp.diff_commonOverlap_('123456xxx', 'xxxabcd'));100 // Unicode.101 // Some overly clever languages (C#) may treat ligatures as equal to their102 // component letters. E.g. U+FB01 == 'fi'103 assertEquals(0, dmp.diff_commonOverlap_('fi', '\ufb01i'));104}105function testDiffHalfMatch() {106 // Detect a halfmatch.107 dmp.Diff_Timeout = 1;108 // No match.109 assertEquals(null, dmp.diff_halfMatch_('1234567890', 'abcdef'));110 assertEquals(null, dmp.diff_halfMatch_('12345', '23'));111 // Single Match.112 assertEquivalent(['12', '90', 'a', 'z', '345678'], dmp.diff_halfMatch_('1234567890', 'a345678z'));113 assertEquivalent(['a', 'z', '12', '90', '345678'], dmp.diff_halfMatch_('a345678z', '1234567890'));114 assertEquivalent(['abc', 'z', '1234', '0', '56789'], dmp.diff_halfMatch_('abc56789z', '1234567890'));115 assertEquivalent(['a', 'xyz', '1', '7890', '23456'], dmp.diff_halfMatch_('a23456xyz', '1234567890'));116 // Multiple Matches.117 assertEquivalent(['12123', '123121', 'a', 'z', '1234123451234'], dmp.diff_halfMatch_('121231234123451234123121', 'a1234123451234z'));118 assertEquivalent(['', '-=-=-=-=-=', 'x', '', 'x-=-=-=-=-=-=-='], dmp.diff_halfMatch_('x-=-=-=-=-=-=-=-=-=-=-=-=', 'xx-=-=-=-=-=-=-='));119 assertEquivalent(['-=-=-=-=-=', '', '', 'y', '-=-=-=-=-=-=-=y'], dmp.diff_halfMatch_('-=-=-=-=-=-=-=-=-=-=-=-=y', '-=-=-=-=-=-=-=yy'));120 // Non-optimal halfmatch.121 // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy122 assertEquivalent(['qHillo', 'w', 'x', 'Hulloy', 'HelloHe'], dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));123 // Optimal no halfmatch.124 dmp.Diff_Timeout = 0;125 assertEquals(null, dmp.diff_halfMatch_('qHilloHelloHew', 'xHelloHeHulloy'));126}127function testDiffLinesToChars() {128 function assertLinesToCharsResultEquals(a, b) {129 assertEquals(a.chars1, b.chars1);130 assertEquals(a.chars2, b.chars2);131 assertEquivalent(a.lineArray, b.lineArray);132 }133 // Convert lines down to characters.134 assertLinesToCharsResultEquals({chars1: '\x01\x02\x01', chars2: '\x02\x01\x02', lineArray: ['', 'alpha\n', 'beta\n']}, dmp.diff_linesToChars_('alpha\nbeta\nalpha\n', 'beta\nalpha\nbeta\n'));135 assertLinesToCharsResultEquals({chars1: '', chars2: '\x01\x02\x03\x03', lineArray: ['', 'alpha\r\n', 'beta\r\n', '\r\n']}, dmp.diff_linesToChars_('', 'alpha\r\nbeta\r\n\r\n\r\n'));136 assertLinesToCharsResultEquals({chars1: '\x01', chars2: '\x02', lineArray: ['', 'a', 'b']}, dmp.diff_linesToChars_('a', 'b'));137 // More than 256 to reveal any 8-bit limitations.138 var n = 300;139 var lineList = [];140 var charList = [];141 for (var x = 1; x < n + 1; x++) {142 lineList[x - 1] = x + '\n';143 charList[x - 1] = String.fromCharCode(x);144 }145 assertEquals(n, lineList.length);146 var lines = lineList.join('');147 var chars = charList.join('');148 assertEquals(n, chars.length);149 lineList.unshift('');150 assertLinesToCharsResultEquals({chars1: chars, chars2: '', lineArray: lineList}, dmp.diff_linesToChars_(lines, ''));151}152function testDiffCharsToLines() {153 // Convert chars up to lines.154 var diffs = [[DIFF_EQUAL, '\x01\x02\x01'], [DIFF_INSERT, '\x02\x01\x02']];155 dmp.diff_charsToLines_(diffs, ['', 'alpha\n', 'beta\n']);156 assertEquivalent([[DIFF_EQUAL, 'alpha\nbeta\nalpha\n'], [DIFF_INSERT, 'beta\nalpha\nbeta\n']], diffs);157 // More than 256 to reveal any 8-bit limitations.158 var n = 300;159 var lineList = [];160 var charList = [];161 for (var x = 1; x < n + 1; x++) {162 lineList[x - 1] = x + '\n';163 charList[x - 1] = String.fromCharCode(x);164 }165 assertEquals(n, lineList.length);166 var lines = lineList.join('');167 var chars = charList.join('');168 assertEquals(n, chars.length);169 lineList.unshift('');170 var diffs = [[DIFF_DELETE, chars]];171 dmp.diff_charsToLines_(diffs, lineList);172 assertEquivalent([[DIFF_DELETE, lines]], diffs);173}174function testDiffCleanupMerge() {175 // Cleanup a messy diff.176 // Null case.177 var diffs = [];178 dmp.diff_cleanupMerge(diffs);179 assertEquivalent([], diffs);180 // No change case.181 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']];182 dmp.diff_cleanupMerge(diffs);183 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_INSERT, 'c']], diffs);184 // Merge equalities.185 diffs = [[DIFF_EQUAL, 'a'], [DIFF_EQUAL, 'b'], [DIFF_EQUAL, 'c']];186 dmp.diff_cleanupMerge(diffs);187 assertEquivalent([[DIFF_EQUAL, 'abc']], diffs);188 // Merge deletions.189 diffs = [[DIFF_DELETE, 'a'], [DIFF_DELETE, 'b'], [DIFF_DELETE, 'c']];190 dmp.diff_cleanupMerge(diffs);191 assertEquivalent([[DIFF_DELETE, 'abc']], diffs);192 // Merge insertions.193 diffs = [[DIFF_INSERT, 'a'], [DIFF_INSERT, 'b'], [DIFF_INSERT, 'c']];194 dmp.diff_cleanupMerge(diffs);195 assertEquivalent([[DIFF_INSERT, 'abc']], diffs);196 // Merge interweave.197 diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b'], [DIFF_DELETE, 'c'], [DIFF_INSERT, 'd'], [DIFF_EQUAL, 'e'], [DIFF_EQUAL, 'f']];198 dmp.diff_cleanupMerge(diffs);199 assertEquivalent([[DIFF_DELETE, 'ac'], [DIFF_INSERT, 'bd'], [DIFF_EQUAL, 'ef']], diffs);200 // Prefix and suffix detection.201 diffs = [[DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc']];202 dmp.diff_cleanupMerge(diffs);203 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'c']], diffs);204 // Prefix and suffix detection with equalities.205 diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'a'], [DIFF_INSERT, 'abc'], [DIFF_DELETE, 'dc'], [DIFF_EQUAL, 'y']];206 dmp.diff_cleanupMerge(diffs);207 assertEquivalent([[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'd'], [DIFF_INSERT, 'b'], [DIFF_EQUAL, 'cy']], diffs);208 // Slide edit left.209 diffs = [[DIFF_EQUAL, 'a'], [DIFF_INSERT, 'ba'], [DIFF_EQUAL, 'c']];210 dmp.diff_cleanupMerge(diffs);211 assertEquivalent([[DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'ac']], diffs);212 // Slide edit right.213 diffs = [[DIFF_EQUAL, 'c'], [DIFF_INSERT, 'ab'], [DIFF_EQUAL, 'a']];214 dmp.diff_cleanupMerge(diffs);215 assertEquivalent([[DIFF_EQUAL, 'ca'], [DIFF_INSERT, 'ba']], diffs);216 // Slide edit left recursive.217 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'ac'], [DIFF_EQUAL, 'x']];218 dmp.diff_cleanupMerge(diffs);219 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'acx']], diffs);220 // Slide edit right recursive.221 diffs = [[DIFF_EQUAL, 'x'], [DIFF_DELETE, 'ca'], [DIFF_EQUAL, 'c'], [DIFF_DELETE, 'b'], [DIFF_EQUAL, 'a']];222 dmp.diff_cleanupMerge(diffs);223 assertEquivalent([[DIFF_EQUAL, 'xca'], [DIFF_DELETE, 'cba']], diffs);224}225function testDiffCleanupSemanticLossless() {226 // Slide diffs to match logical boundaries.227 // Null case.228 var diffs = [];229 dmp.diff_cleanupSemanticLossless(diffs);230 assertEquivalent([], diffs);231 // Blank lines.232 diffs = [[DIFF_EQUAL, 'AAA\r\n\r\nBBB'], [DIFF_INSERT, '\r\nDDD\r\n\r\nBBB'], [DIFF_EQUAL, '\r\nEEE']];233 dmp.diff_cleanupSemanticLossless(diffs);234 assertEquivalent([[DIFF_EQUAL, 'AAA\r\n\r\n'], [DIFF_INSERT, 'BBB\r\nDDD\r\n\r\n'], [DIFF_EQUAL, 'BBB\r\nEEE']], diffs);235 // Line boundaries.236 diffs = [[DIFF_EQUAL, 'AAA\r\nBBB'], [DIFF_INSERT, ' DDD\r\nBBB'], [DIFF_EQUAL, ' EEE']];237 dmp.diff_cleanupSemanticLossless(diffs);238 assertEquivalent([[DIFF_EQUAL, 'AAA\r\n'], [DIFF_INSERT, 'BBB DDD\r\n'], [DIFF_EQUAL, 'BBB EEE']], diffs);239 // Word boundaries.240 diffs = [[DIFF_EQUAL, 'The c'], [DIFF_INSERT, 'ow and the c'], [DIFF_EQUAL, 'at.']];241 dmp.diff_cleanupSemanticLossless(diffs);242 assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_INSERT, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);243 // Alphanumeric boundaries.244 diffs = [[DIFF_EQUAL, 'The-c'], [DIFF_INSERT, 'ow-and-the-c'], [DIFF_EQUAL, 'at.']];245 dmp.diff_cleanupSemanticLossless(diffs);246 assertEquivalent([[DIFF_EQUAL, 'The-'], [DIFF_INSERT, 'cow-and-the-'], [DIFF_EQUAL, 'cat.']], diffs);247 // Hitting the start.248 diffs = [[DIFF_EQUAL, 'a'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'ax']];249 dmp.diff_cleanupSemanticLossless(diffs);250 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'aax']], diffs);251 // Hitting the end.252 diffs = [[DIFF_EQUAL, 'xa'], [DIFF_DELETE, 'a'], [DIFF_EQUAL, 'a']];253 dmp.diff_cleanupSemanticLossless(diffs);254 assertEquivalent([[DIFF_EQUAL, 'xaa'], [DIFF_DELETE, 'a']], diffs);255 // Sentence boundaries.256 diffs = [[DIFF_EQUAL, 'The xxx. The '], [DIFF_INSERT, 'zzz. The '], [DIFF_EQUAL, 'yyy.']];257 dmp.diff_cleanupSemanticLossless(diffs);258 assertEquivalent([[DIFF_EQUAL, 'The xxx.'], [DIFF_INSERT, ' The zzz.'], [DIFF_EQUAL, ' The yyy.']], diffs);259}260function testDiffCleanupSemantic() {261 // Cleanup semantically trivial equalities.262 // Null case.263 var diffs = [];264 dmp.diff_cleanupSemantic(diffs);265 assertEquivalent([], diffs);266 // No elimination #1.267 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']];268 dmp.diff_cleanupSemantic(diffs);269 assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, 'cd'], [DIFF_EQUAL, '12'], [DIFF_DELETE, 'e']], diffs);270 // No elimination #2.271 diffs = [[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']];272 dmp.diff_cleanupSemantic(diffs);273 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'ABC'], [DIFF_EQUAL, '1234'], [DIFF_DELETE, 'wxyz']], diffs);274 // Simple elimination.275 diffs = [[DIFF_DELETE, 'a'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, 'c']];276 dmp.diff_cleanupSemantic(diffs);277 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_INSERT, 'b']], diffs);278 // Backpass elimination.279 diffs = [[DIFF_DELETE, 'ab'], [DIFF_EQUAL, 'cd'], [DIFF_DELETE, 'e'], [DIFF_EQUAL, 'f'], [DIFF_INSERT, 'g']];280 dmp.diff_cleanupSemantic(diffs);281 assertEquivalent([[DIFF_DELETE, 'abcdef'], [DIFF_INSERT, 'cdfg']], diffs);282 // Multiple eliminations.283 diffs = [[DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2'], [DIFF_EQUAL, '_'], [DIFF_INSERT, '1'], [DIFF_EQUAL, 'A'], [DIFF_DELETE, 'B'], [DIFF_INSERT, '2']];284 dmp.diff_cleanupSemantic(diffs);285 assertEquivalent([[DIFF_DELETE, 'AB_AB'], [DIFF_INSERT, '1A2_1A2']], diffs);286 // Word boundaries.287 diffs = [[DIFF_EQUAL, 'The c'], [DIFF_DELETE, 'ow and the c'], [DIFF_EQUAL, 'at.']];288 dmp.diff_cleanupSemantic(diffs);289 assertEquivalent([[DIFF_EQUAL, 'The '], [DIFF_DELETE, 'cow and the '], [DIFF_EQUAL, 'cat.']], diffs);290 // No overlap elimination.291 diffs = [[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']];292 dmp.diff_cleanupSemantic(diffs);293 assertEquivalent([[DIFF_DELETE, 'abcxx'], [DIFF_INSERT, 'xxdef']], diffs);294 // Overlap elimination.295 diffs = [[DIFF_DELETE, 'abcxxx'], [DIFF_INSERT, 'xxxdef']];296 dmp.diff_cleanupSemantic(diffs);297 assertEquivalent([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xxx'], [DIFF_INSERT, 'def']], diffs);298 // Reverse overlap elimination.299 diffs = [[DIFF_DELETE, 'xxxabc'], [DIFF_INSERT, 'defxxx']];300 dmp.diff_cleanupSemantic(diffs);301 assertEquivalent([[DIFF_INSERT, 'def'], [DIFF_EQUAL, 'xxx'], [DIFF_DELETE, 'abc']], diffs);302 // Two overlap eliminations.303 diffs = [[DIFF_DELETE, 'abcd1212'], [DIFF_INSERT, '1212efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A3'], [DIFF_INSERT, '3BC']];304 dmp.diff_cleanupSemantic(diffs);305 assertEquivalent([[DIFF_DELETE, 'abcd'], [DIFF_EQUAL, '1212'], [DIFF_INSERT, 'efghi'], [DIFF_EQUAL, '----'], [DIFF_DELETE, 'A'], [DIFF_EQUAL, '3'], [DIFF_INSERT, 'BC']], diffs);306}307function testDiffCleanupEfficiency() {308 // Cleanup operationally trivial equalities.309 dmp.Diff_EditCost = 4;310 // Null case.311 var diffs = [];312 dmp.diff_cleanupEfficiency(diffs);313 assertEquivalent([], diffs);314 // No elimination.315 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];316 dmp.diff_cleanupEfficiency(diffs);317 assertEquivalent([[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']], diffs);318 // Four-edit elimination.319 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];320 dmp.diff_cleanupEfficiency(diffs);321 assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xyz34']], diffs);322 // Three-edit elimination.323 diffs = [[DIFF_INSERT, '12'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];324 dmp.diff_cleanupEfficiency(diffs);325 assertEquivalent([[DIFF_DELETE, 'xcd'], [DIFF_INSERT, '12x34']], diffs);326 // Backpass elimination.327 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'xy'], [DIFF_INSERT, '34'], [DIFF_EQUAL, 'z'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '56']];328 dmp.diff_cleanupEfficiency(diffs);329 assertEquivalent([[DIFF_DELETE, 'abxyzcd'], [DIFF_INSERT, '12xy34z56']], diffs);330 // High cost elimination.331 dmp.Diff_EditCost = 5;332 diffs = [[DIFF_DELETE, 'ab'], [DIFF_INSERT, '12'], [DIFF_EQUAL, 'wxyz'], [DIFF_DELETE, 'cd'], [DIFF_INSERT, '34']];333 dmp.diff_cleanupEfficiency(diffs);334 assertEquivalent([[DIFF_DELETE, 'abwxyzcd'], [DIFF_INSERT, '12wxyz34']], diffs);335 dmp.Diff_EditCost = 4;336}337function testDiffPrettyHtml() {338 // Pretty print.339 var diffs = [[DIFF_EQUAL, 'a\n'], [DIFF_DELETE, '<B>b</B>'], [DIFF_INSERT, 'c&d']];340 assertEquals('<span>a¶<br></span><del style="background:#ffe6e6;"><B>b</B></del><ins style="background:#e6ffe6;">c&d</ins>', dmp.diff_prettyHtml(diffs));341}342function testDiffText() {343 // Compute the source and destination texts.344 var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy']];345 assertEquals('jumps over the lazy', dmp.diff_text1(diffs));346 assertEquals('jumped over a lazy', dmp.diff_text2(diffs));347}348function testDiffDelta() {349 // Convert a diff into delta string.350 var diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, ' lazy'], [DIFF_INSERT, 'old dog']];351 var text1 = dmp.diff_text1(diffs);352 assertEquals('jumps over the lazy', text1);353 var delta = dmp.diff_toDelta(diffs);354 assertEquals('=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog', delta);355 // Convert delta string into a diff.356 assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));357 // Generates error (19 != 20).358 try {359 dmp.diff_fromDelta(text1 + 'x', delta);360 assertEquals(Error, null);361 } catch (e) {362 // Exception expected.363 }364 // Generates error (19 != 18).365 try {366 dmp.diff_fromDelta(text1.substring(1), delta);367 assertEquals(Error, null);368 } catch (e) {369 // Exception expected.370 }371 // Generates error (%c3%xy invalid Unicode).372 try {373 dmp.diff_fromDelta('', '+%c3%xy');374 assertEquals(Error, null);375 } catch (e) {376 // Exception expected.377 }378 // Test deltas with special characters.379 diffs = [[DIFF_EQUAL, '\u0680 \x00 \t %'], [DIFF_DELETE, '\u0681 \x01 \n ^'], [DIFF_INSERT, '\u0682 \x02 \\ |']];380 text1 = dmp.diff_text1(diffs);381 assertEquals('\u0680 \x00 \t %\u0681 \x01 \n ^', text1);382 delta = dmp.diff_toDelta(diffs);383 assertEquals('=7\t-7\t+%DA%82 %02 %5C %7C', delta);384 // Convert delta string into a diff.385 assertEquivalent(diffs, dmp.diff_fromDelta(text1, delta));386 // Verify pool of unchanged characters.387 diffs = [[DIFF_INSERT, 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ']];388 var text2 = dmp.diff_text2(diffs);389 assertEquals('A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', text2);390 delta = dmp.diff_toDelta(diffs);391 assertEquals('+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ', delta);392 // Convert delta string into a diff.393 assertEquivalent(diffs, dmp.diff_fromDelta('', delta));394}395function testDiffXIndex() {396 // Translate a location in text1 to text2.397 // Translation on equality.398 assertEquals(5, dmp.diff_xIndex([[DIFF_DELETE, 'a'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']], 2));399 // Translation on deletion.400 assertEquals(1, dmp.diff_xIndex([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '1234'], [DIFF_EQUAL, 'xyz']], 3));401}402function testDiffLevenshtein() {403 // Levenshtein with trailing equality.404 assertEquals(4, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234'], [DIFF_EQUAL, 'xyz']]));405 // Levenshtein with leading equality.406 assertEquals(4, dmp.diff_levenshtein([[DIFF_EQUAL, 'xyz'], [DIFF_DELETE, 'abc'], [DIFF_INSERT, '1234']]));407 // Levenshtein with middle equality.408 assertEquals(7, dmp.diff_levenshtein([[DIFF_DELETE, 'abc'], [DIFF_EQUAL, 'xyz'], [DIFF_INSERT, '1234']]));409}410function testDiffBisect() {411 // Normal.412 var a = 'cat';413 var b = 'map';414 // Since the resulting diff hasn't been normalized, it would be ok if415 // the insertion and deletion pairs are swapped.416 // If the order changes, tweak this test as required.417 assertEquivalent([[DIFF_DELETE, 'c'], [DIFF_INSERT, 'm'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 't'], [DIFF_INSERT, 'p']], dmp.diff_bisect_(a, b, Number.MAX_VALUE));418 // Timeout.419 assertEquivalent([[DIFF_DELETE, 'cat'], [DIFF_INSERT, 'map']], dmp.diff_bisect_(a, b, 0));420}421function testDiffMain() {422 // Perform a trivial diff.423 // Null case.424 assertEquivalent([], dmp.diff_main('', '', false));425 // Equality.426 assertEquivalent([[DIFF_EQUAL, 'abc']], dmp.diff_main('abc', 'abc', false));427 // Simple insertion.428 assertEquivalent([[DIFF_EQUAL, 'ab'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'ab123c', false));429 // Simple deletion.430 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'bc']], dmp.diff_main('a123bc', 'abc', false));431 // Two insertions.432 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_INSERT, '123'], [DIFF_EQUAL, 'b'], [DIFF_INSERT, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('abc', 'a123b456c', false));433 // Two deletions.434 assertEquivalent([[DIFF_EQUAL, 'a'], [DIFF_DELETE, '123'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '456'], [DIFF_EQUAL, 'c']], dmp.diff_main('a123b456c', 'abc', false));435 // Perform a real diff.436 // Switch off the timeout.437 dmp.Diff_Timeout = 0;438 // Simple cases.439 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, 'b']], dmp.diff_main('a', 'b', false));440 assertEquivalent([[DIFF_DELETE, 'Apple'], [DIFF_INSERT, 'Banana'], [DIFF_EQUAL, 's are a'], [DIFF_INSERT, 'lso'], [DIFF_EQUAL, ' fruit.']], dmp.diff_main('Apples are a fruit.', 'Bananas are also fruit.', false));441 assertEquivalent([[DIFF_DELETE, 'a'], [DIFF_INSERT, '\u0680'], [DIFF_EQUAL, 'x'], [DIFF_DELETE, '\t'], [DIFF_INSERT, '\0']], dmp.diff_main('ax\t', '\u0680x\0', false));442 // Overlaps.443 assertEquivalent([[DIFF_DELETE, '1'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, 'y'], [DIFF_EQUAL, 'b'], [DIFF_DELETE, '2'], [DIFF_INSERT, 'xab']], dmp.diff_main('1ayb2', 'abxab', false));444 assertEquivalent([[DIFF_INSERT, 'xaxcx'], [DIFF_EQUAL, 'abc'], [DIFF_DELETE, 'y']], dmp.diff_main('abcy', 'xaxcxabc', false));445 assertEquivalent([[DIFF_DELETE, 'ABCD'], [DIFF_EQUAL, 'a'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'bcd'], [DIFF_DELETE, '='], [DIFF_INSERT, '-'], [DIFF_EQUAL, 'efghijklmnopqrs'], [DIFF_DELETE, 'EFGHIJKLMNOefg']], dmp.diff_main('ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg', 'a-bcd-efghijklmnopqrs', false));446 // Large equality.447 assertEquivalent([[DIFF_INSERT, ' '], [DIFF_EQUAL, 'a'], [DIFF_INSERT, 'nd'], [DIFF_EQUAL, ' [[Pennsylvania]]'], [DIFF_DELETE, ' and [[New']], dmp.diff_main('a [[Pennsylvania]] and [[New', ' and [[Pennsylvania]]', false));448 // Timeout.449 dmp.Diff_Timeout = 0.1; // 100ms450 var a = '`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n';451 var b = 'I am the very model of a modern major general,\nI\'ve information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n';452 // Increase the text lengths by 1024 times to ensure a timeout.453 for (var x = 0; x < 10; x++) {454 a = a + a;455 b = b + b;456 }457 var startTime = (new Date()).getTime();458 dmp.diff_main(a, b);459 var endTime = (new Date()).getTime();460 // Test that we took at least the timeout period.461 assertTrue(dmp.Diff_Timeout * 1000 <= endTime - startTime);462 // Test that we didn't take forever (be forgiving).463 // Theoretically this test could fail very occasionally if the464 // OS task swaps or locks up for a second at the wrong moment.465 // ****466 // TODO(fraser): For unknown reasons this is taking 500 ms on Google's467 // internal test system. Whereas browsers take 140 ms.468 //assertTrue(dmp.Diff_Timeout * 1000 * 2 > endTime - startTime);469 // ****470 dmp.Diff_Timeout = 0;471 // Test the linemode speedup.472 // Must be long to pass the 100 char cutoff.473 // Simple line-mode.474 a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';475 b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n';476 assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));477 // Single line-mode.478 a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890';479 b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij';480 assertEquivalent(dmp.diff_main(a, b, false), dmp.diff_main(a, b, true));481 // Overlap line-mode.482 a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n';483 b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n';484 var texts_linemode = diff_rebuildtexts(dmp.diff_main(a, b, true));485 var texts_textmode = diff_rebuildtexts(dmp.diff_main(a, b, false));486 assertEquivalent(texts_textmode, texts_linemode);487 // Test null inputs.488 try {489 dmp.diff_main(null, null);490 assertEquals(Error, null);491 } catch (e) {492 // Exception expected.493 }494}495// MATCH TEST FUNCTIONS496function testMatchAlphabet() {497 // Initialise the bitmasks for Bitap.498 // Unique.499 assertEquivalent({'a':4, 'b':2, 'c':1}, dmp.match_alphabet_('abc'));500 // Duplicates.501 assertEquivalent({'a':37, 'b':18, 'c':8}, dmp.match_alphabet_('abcaba'));502}503function testMatchBitap() {504 // Bitap algorithm.505 dmp.Match_Distance = 100;506 dmp.Match_Threshold = 0.5;507 // Exact matches.508 assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 5));509 assertEquals(5, dmp.match_bitap_('abcdefghijk', 'fgh', 0));510 // Fuzzy matches.511 assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxhi', 0));512 assertEquals(2, dmp.match_bitap_('abcdefghijk', 'cdefxyhijk', 5));513 assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'bxy', 1));514 // Overflow.515 assertEquals(2, dmp.match_bitap_('123456789xx0', '3456789x0', 2));516 // Threshold test.517 dmp.Match_Threshold = 0.4;518 assertEquals(4, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));519 dmp.Match_Threshold = 0.3;520 assertEquals(-1, dmp.match_bitap_('abcdefghijk', 'efxyhi', 1));521 dmp.Match_Threshold = 0.0;522 assertEquals(1, dmp.match_bitap_('abcdefghijk', 'bcdef', 1));523 dmp.Match_Threshold = 0.5;524 // Multiple select.525 assertEquals(0, dmp.match_bitap_('abcdexyzabcde', 'abccde', 3));526 assertEquals(8, dmp.match_bitap_('abcdexyzabcde', 'abccde', 5));527 // Distance test.528 dmp.Match_Distance = 10; // Strict location.529 assertEquals(-1, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));530 assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdxxefg', 1));531 dmp.Match_Distance = 1000; // Loose location.532 assertEquals(0, dmp.match_bitap_('abcdefghijklmnopqrstuvwxyz', 'abcdefg', 24));533}534function testMatchMain() {535 // Full match.536 // Shortcut matches.537 assertEquals(0, dmp.match_main('abcdef', 'abcdef', 1000));538 assertEquals(-1, dmp.match_main('', 'abcdef', 1));539 assertEquals(3, dmp.match_main('abcdef', '', 3));540 assertEquals(3, dmp.match_main('abcdef', 'de', 3));541 // Beyond end match.542 assertEquals(3, dmp.match_main("abcdef", "defy", 4));543 // Oversized pattern.544 assertEquals(0, dmp.match_main("abcdef", "abcdefy", 0));545 // Complex match.546 assertEquals(4, dmp.match_main('I am the very model of a modern major general.', ' that berry ', 5));547 // Test null inputs.548 try {549 dmp.match_main(null, null, 0);550 assertEquals(Error, null);551 } catch (e) {552 // Exception expected.553 }554}555// PATCH TEST FUNCTIONS556function testPatchObj() {557 // Patch Object.558 var p = new diff_match_patch.patch_obj();559 p.start1 = 20;560 p.start2 = 21;561 p.length1 = 18;562 p.length2 = 17;563 p.diffs = [[DIFF_EQUAL, 'jump'], [DIFF_DELETE, 's'], [DIFF_INSERT, 'ed'], [DIFF_EQUAL, ' over '], [DIFF_DELETE, 'the'], [DIFF_INSERT, 'a'], [DIFF_EQUAL, '\nlaz']];564 var strp = p.toString();565 assertEquals('@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n', strp);566}567function testPatchFromText() {568 assertEquivalent([], dmp.patch_fromText(strp));569 var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n';570 assertEquals(strp, dmp.patch_fromText(strp)[0].toString());571 assertEquals('@@ -1 +1 @@\n-a\n+b\n', dmp.patch_fromText('@@ -1 +1 @@\n-a\n+b\n')[0].toString());572 assertEquals('@@ -1,3 +0,0 @@\n-abc\n', dmp.patch_fromText('@@ -1,3 +0,0 @@\n-abc\n')[0].toString());573 assertEquals('@@ -0,0 +1,3 @@\n+abc\n', dmp.patch_fromText('@@ -0,0 +1,3 @@\n+abc\n')[0].toString());574 // Generates error.575 try {576 dmp.patch_fromText('Bad\nPatch\n');577 assertEquals(Error, null);578 } catch (e) {579 // Exception expected.580 }581}582function testPatchToText() {583 var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';584 var p = dmp.patch_fromText(strp);585 assertEquals(strp, dmp.patch_toText(p));586 strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n';587 p = dmp.patch_fromText(strp);588 assertEquals(strp, dmp.patch_toText(p));589}590function testPatchAddContext() {591 dmp.Patch_Margin = 4;592 var p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];593 dmp.patch_addContext_(p, 'The quick brown fox jumps over the lazy dog.');594 assertEquals('@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n', p.toString());595 // Same, but not enough trailing context.596 p = dmp.patch_fromText('@@ -21,4 +21,10 @@\n-jump\n+somersault\n')[0];597 dmp.patch_addContext_(p, 'The quick brown fox jumps.');598 assertEquals('@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n', p.toString());599 // Same, but not enough leading context.600 p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];601 dmp.patch_addContext_(p, 'The quick brown fox jumps.');602 assertEquals('@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n', p.toString());603 // Same, but with ambiguity.604 p = dmp.patch_fromText('@@ -3 +3,2 @@\n-e\n+at\n')[0];605 dmp.patch_addContext_(p, 'The quick brown fox jumps. The quick brown fox crashes.');606 assertEquals('@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n', p.toString());607}608function testPatchMake() {609 // Null case.610 var patches = dmp.patch_make('', '');611 assertEquals('', dmp.patch_toText(patches));612 var text1 = 'The quick brown fox jumps over the lazy dog.';613 var text2 = 'That quick brown fox jumped over a lazy dog.';614 // Text2+Text1 inputs.615 var expectedPatch = '@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n';616 // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.617 patches = dmp.patch_make(text2, text1);618 assertEquals(expectedPatch, dmp.patch_toText(patches));619 // Text1+Text2 inputs.620 expectedPatch = '@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n';621 patches = dmp.patch_make(text1, text2);622 assertEquals(expectedPatch, dmp.patch_toText(patches));623 // Diff input.624 var diffs = dmp.diff_main(text1, text2, false);625 patches = dmp.patch_make(diffs);626 assertEquals(expectedPatch, dmp.patch_toText(patches));627 // Text1+Diff inputs.628 patches = dmp.patch_make(text1, diffs);629 assertEquals(expectedPatch, dmp.patch_toText(patches));630 // Text1+Text2+Diff inputs (deprecated).631 patches = dmp.patch_make(text1, text2, diffs);632 assertEquals(expectedPatch, dmp.patch_toText(patches));633 // Character encoding.634 patches = dmp.patch_make('`1234567890-=[]\\;\',./', '~!@#$%^&*()_+{}|:"<>?');635 assertEquals('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n', dmp.patch_toText(patches));636 // Character decoding.637 diffs = [[DIFF_DELETE, '`1234567890-=[]\\;\',./'], [DIFF_INSERT, '~!@#$%^&*()_+{}|:"<>?']];638 assertEquivalent(diffs, dmp.patch_fromText('@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n')[0].diffs);639 // Long string with repeats.640 text1 = '';641 for (var x = 0; x < 100; x++) {642 text1 += 'abcdef';643 }644 text2 = text1 + '123';645 expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n';646 patches = dmp.patch_make(text1, text2);647 assertEquals(expectedPatch, dmp.patch_toText(patches));648 // Test null inputs.649 try {650 dmp.patch_make(null);651 assertEquals(Error, null);652 } catch (e) {653 // Exception expected.654 }655}656function testPatchSplitMax() {657 // Assumes that dmp.Match_MaxBits is 32.658 var patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz01234567890', 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0');659 dmp.patch_splitMax(patches);660 assertEquals('@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n', dmp.patch_toText(patches));661 patches = dmp.patch_make('abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz', 'abcdefuvwxyz');662 var oldToText = dmp.patch_toText(patches);663 dmp.patch_splitMax(patches);664 assertEquals(oldToText, dmp.patch_toText(patches));665 patches = dmp.patch_make('1234567890123456789012345678901234567890123456789012345678901234567890', 'abc');666 dmp.patch_splitMax(patches);667 assertEquals('@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n', dmp.patch_toText(patches));668 patches = dmp.patch_make('abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1', 'abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1');669 dmp.patch_splitMax(patches);670 assertEquals('@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n', dmp.patch_toText(patches));671}672function testPatchAddPadding() {673 // Both edges full.674 var patches = dmp.patch_make('', 'test');675 assertEquals('@@ -0,0 +1,4 @@\n+test\n', dmp.patch_toText(patches));676 dmp.patch_addPadding(patches);677 assertEquals('@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n', dmp.patch_toText(patches));678 // Both edges partial.679 patches = dmp.patch_make('XY', 'XtestY');680 assertEquals('@@ -1,2 +1,6 @@\n X\n+test\n Y\n', dmp.patch_toText(patches));681 dmp.patch_addPadding(patches);682 assertEquals('@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n', dmp.patch_toText(patches));683 // Both edges none.684 patches = dmp.patch_make('XXXXYYYY', 'XXXXtestYYYY');685 assertEquals('@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));686 dmp.patch_addPadding(patches);687 assertEquals('@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n', dmp.patch_toText(patches));688}689function testPatchApply() {690 dmp.Match_Distance = 1000;691 dmp.Match_Threshold = 0.5;692 dmp.Patch_DeleteThreshold = 0.5;693 // Null case.694 var patches = dmp.patch_make('', '');695 var results = dmp.patch_apply(patches, 'Hello world.');696 assertEquivalent(['Hello world.', []], results);697 // Exact match.698 patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'That quick brown fox jumped over a lazy dog.');699 results = dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');700 assertEquivalent(['That quick brown fox jumped over a lazy dog.', [true, true]], results);701 // Partial match.702 results = dmp.patch_apply(patches, 'The quick red rabbit jumps over the tired tiger.');703 assertEquivalent(['That quick red rabbit jumped over a tired tiger.', [true, true]], results);704 // Failed match.705 results = dmp.patch_apply(patches, 'I am the very model of a modern major general.');706 assertEquivalent(['I am the very model of a modern major general.', [false, false]], results);707 // Big delete, small change.708 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');709 results = dmp.patch_apply(patches, 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y');710 assertEquivalent(['xabcy', [true, true]], results);711 // Big delete, big change 1.712 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');713 results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');714 assertEquivalent(['xabc12345678901234567890---------------++++++++++---------------12345678901234567890y', [false, true]], results);715 // Big delete, big change 2.716 dmp.Patch_DeleteThreshold = 0.6;717 patches = dmp.patch_make('x1234567890123456789012345678901234567890123456789012345678901234567890y', 'xabcy');718 results = dmp.patch_apply(patches, 'x12345678901234567890---------------++++++++++---------------12345678901234567890y');719 assertEquivalent(['xabcy', [true, true]], results);720 dmp.Patch_DeleteThreshold = 0.5;721 // Compensate for failed patch.722 dmp.Match_Threshold = 0.0;723 dmp.Match_Distance = 0;724 patches = dmp.patch_make('abcdefghijklmnopqrstuvwxyz--------------------1234567890', 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890');725 results = dmp.patch_apply(patches, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890');726 assertEquivalent(['ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890', [false, true]], results);727 dmp.Match_Threshold = 0.5;728 dmp.Match_Distance = 1000;729 // No side effects.730 patches = dmp.patch_make('', 'test');731 var patchstr = dmp.patch_toText(patches);732 dmp.patch_apply(patches, '');733 assertEquals(patchstr, dmp.patch_toText(patches));734 // No side effects with major delete.735 patches = dmp.patch_make('The quick brown fox jumps over the lazy dog.', 'Woof');736 patchstr = dmp.patch_toText(patches);737 dmp.patch_apply(patches, 'The quick brown fox jumps over the lazy dog.');738 assertEquals(patchstr, dmp.patch_toText(patches));739 // Edge exact match.740 patches = dmp.patch_make('', 'test');741 results = dmp.patch_apply(patches, '');742 assertEquivalent(['test', [true]], results);743 // Near edge exact match.744 patches = dmp.patch_make('XY', 'XtestY');745 results = dmp.patch_apply(patches, 'XY');746 assertEquivalent(['XtestY', [true]], results);747 // Edge partial match.748 patches = dmp.patch_make('y', 'y123');749 results = dmp.patch_apply(patches, 'x');750 assertEquivalent(['x123', [true]], results);...
fastdiff.js
Source:fastdiff.js
...497 const result = fastDiff( oldText, newText, comparator );498 expect( result ).to.deep.equal( expected, 'fastDiff changes failed' );499 if ( checkDiffToChangesCompatibility ) {500 expect( result ).to.deep.equal(501 diffToChanges( diff( oldText, newText, comparator ), newText ), 'diffToChanges compatibility failed' );502 }503}504function expectDiffLinear( oldText, newText, expected, checkDiffCompatibility = true, comparator = null ) {505 const actions = { d: 'delete', e: 'equal', i: 'insert' };506 const expectedArray = expected.split( '' ).map( item => actions[ item ] );507 const result = fastDiff( oldText, newText, comparator, true );508 expect( result ).to.deep.equal( expectedArray, 'fastDiff linear result failed' );509 if ( checkDiffCompatibility ) {510 expect( result ).to.deep.equal( diff( oldText, newText, comparator ), 'diff compatibility failed' );511 }...
diff.js
Source:diff.js
...29}30exports.diff = {31 "diff" : function (test) {32 test.expect(5);33 test.equal(moment(1000).diff(0), 1000, "1 second - 0 = 1000");34 test.equal(moment(1000).diff(500), 500, "1 second - 0.5 seconds = 500");35 test.equal(moment(0).diff(1000), -1000, "0 - 1 second = -1000");36 test.equal(moment(new Date(1000)).diff(1000), 0, "1 second - 1 second = 0");37 var oneHourDate = new Date(),38 nowDate = new Date(+oneHourDate);39 oneHourDate.setHours(oneHourDate.getHours() + 1);40 test.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, "1 hour from now = 3600000");41 test.done();42 },43 "diff key after" : function (test) {44 test.expect(10);45 test.equal(moment([2010]).diff([2011], 'years'), -1, "year diff");46 test.equal(moment([2010]).diff([2010, 2], 'months'), -2, "month diff");47 test.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, "week diff");48 test.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, "week diff");49 test.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, "week diff");50 test.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, "week diff");51 test.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, "day diff");52 test.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, "hour diff");53 test.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, "minute diff");54 test.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, "second diff");55 test.done();56 },57 "diff key before" : function (test) {58 test.expect(10);59 test.equal(moment([2011]).diff([2010], 'years'), 1, "year diff");60 test.equal(moment([2010, 2]).diff([2010], 'months'), 2, "month diff");61 test.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, "day diff");62 test.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, "week diff");63 test.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, "week diff");64 test.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, "week diff");65 test.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, "week diff");66 test.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, "hour diff");67 test.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, "minute diff");68 test.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, "second diff");69 test.done();70 },71 "diff key before singular" : function (test) {72 test.expect(10);73 test.equal(moment([2011]).diff([2010], 'year'), 1, "year diff singular");74 test.equal(moment([2010, 2]).diff([2010], 'month'), 2, "month diff singular");75 test.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, "day diff singular");76 test.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, "week diff singular");77 test.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, "week diff singular");78 test.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, "week diff singular");79 test.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, "week diff singular");80 test.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, "hour diff singular");81 test.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, "minute diff singular");82 test.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, "second diff singular");83 test.done();84 },85 "diff key before abbreviated" : function (test) {86 test.expect(10);87 test.equal(moment([2011]).diff([2010], 'y'), 1, "year diff abbreviated");88 test.equal(moment([2010, 2]).diff([2010], 'M'), 2, "month diff abbreviated");89 test.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, "day diff abbreviated");90 test.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, "week diff abbreviated");91 test.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, "week diff abbreviated");92 test.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, "week diff abbreviated");93 test.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, "week diff abbreviated");94 test.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, "hour diff abbreviated");95 test.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, "minute diff abbreviated");96 test.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, "second diff abbreviated");97 test.done();98 },99 "diff month" : function (test) {100 test.expect(1);101 test.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, "month diff");102 test.done();103 },104 "diff across DST" : function (test) {105 var dst = dstForYear(2012), a, b, daysInMonth;106 if (!dst) {107 console.log("No DST?");108 test.done();109 return;110 }111 test.expect(16);112 a = dst.moment;113 b = a.clone().utc().add(12, 'hours').local();114 daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;115 equal(test, b.diff(a, 'ms', true), 12 * 60 * 60 * 1000, "ms diff across DST");116 equal(test, b.diff(a, 's', true), 12 * 60 * 60, "second diff across DST");117 equal(test, b.diff(a, 'm', true), 12 * 60, "minute diff across DST");118 equal(test, b.diff(a, 'h', true), 12, "hour diff across DST");119 equal(test, b.diff(a, 'd', true), (12 - dst.diff) / 24, "day diff across DST");120 equal(test, b.diff(a, 'w', true), (12 - dst.diff) / 24 / 7, "week diff across DST");121 equal(test, b.diff(a, 'M', true), (12 - dst.diff) / 24 / daysInMonth, "month diff across DST");122 equal(test, b.diff(a, 'y', true), (12 - dst.diff) / 24 / daysInMonth / 12, "year diff across DST");123 a = dst.moment;124 b = a.clone().utc().add(12 + dst.diff, 'hours').local();125 daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;126 equal(test, b.diff(a, 'ms', true), (12 + dst.diff) * 60 * 60 * 1000, "ms diff across DST");127 equal(test, b.diff(a, 's', true), (12 + dst.diff) * 60 * 60, "second diff across DST");128 equal(test, b.diff(a, 'm', true), (12 + dst.diff) * 60, "minute diff across DST");129 equal(test, b.diff(a, 'h', true), (12 + dst.diff), "hour diff across DST");130 equal(test, b.diff(a, 'd', true), 12 / 24, "day diff across DST");131 equal(test, b.diff(a, 'w', true), 12 / 24 / 7, "week diff across DST");132 equal(test, b.diff(a, 'M', true), 12 / 24 / daysInMonth, "month diff across DST");133 equal(test, b.diff(a, 'y', true), 12 / 24 / daysInMonth / 12, "year diff across DST");134 test.done();135 },136 "diff overflow" : function (test) {137 test.expect(4);138 test.equal(moment([2011]).diff([2010], 'months'), 12, "month diff");139 test.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, "hour diff");140 test.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, "minute diff");141 test.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, "second diff");142 test.done();143 },144 "diff between utc and local" : function (test) {145 test.expect(7);146 test.equal(moment([2012]).utc().diff([2011], 'years'), 1, "year diff");147 test.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, "month diff");148 test.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, "day diff");149 test.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, "week diff");150 test.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, "hour diff");151 test.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, "minute diff");152 test.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, "second diff");153 test.done();154 },155 "diff floored" : function (test) {156 test.expect(7);157 test.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, "23 hours = 0 days");158 test.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, "23:59 hours = 0 days");159 test.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, "24 hours = 1 day");160 test.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, "year rounded down");161 test.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, "year rounded down");162 test.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, "year rounded down");163 test.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, "year rounded down");164 test.done();165 },166 "year diffs include dates" : function (test) {167 test.expect(1);168 test.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, "year diff should include date of month");169 test.done();170 },171 "month diffs" : function (test) {172 test.expect(8);173 // due to floating point math errors, these tests just need to be accurate within 0.00000001174 equal(test, moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');175 equal(test, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');176 equal(test, moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');177 equal(test, moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');178 equal(test, moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1 + (2 / 30), 'Jan 31 to Feb 29 should be 1 - (2 / 30) months');179 equal(test, moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), -2 + (30 / 31), 'Jan 31 to Mar 1 should be 2 - (30 / 31) months');180 equal(test, moment([2012, 0, 31]).diff([2012, 2, 1, 12], 'months', true), -2 + (29.5 / 31), 'Jan 31 to Mar 1 should be 2 - (29.5 / 31) months');181 equal(test, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');182 test.done();183 },184 "year diffs" : function (test) {185 test.expect(10);186 // due to floating point math errors, these tests just need to be accurate within 0.00000001187 equal(test, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');188 equal(test, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');189 equal(test, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');190 equal(test, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');191 equal(test, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');192 equal(test, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');193 equal(test, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');194 equal(test, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');195 equal(test, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');196 equal(test, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1 + (1 / 28.5) / 12, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');197 test.done();198 }...
diff.qunit.js
Source:diff.qunit.js
...39 { index: 5, type: 'insert' },40 { index: 8, type: 'delete' },41 { index: 8, type: 'delete' }42 ];43 assert.deepEqual(diff(aData8, aData9), aDiff, "diff between data 8 and 9");44 aDiff = [45 { index: 1, type: 'delete' },46 { index: 1, type: 'delete' },47 { index: 3, type: 'insert' },48 { index: 4, type: 'insert' }49 ];50 assert.deepEqual(diff(aData1, aData2), aDiff, "diff between data 1 and 2");51 aDiff = [52 { index: 1, type: 'delete' },53 { index: 1, type: 'delete' },54 { index: 1, type: 'insert' },55 { index: 2, type: 'insert' }56 ];57 assert.deepEqual(diff(aData1, aData3), aDiff, "diff between data 1 and 3");58 aDiff = [59 { index: 1, type: 'insert' },60 { index: 2, type: 'insert' },61 { index: 5, type: 'delete' },62 { index: 5, type: 'delete' }63 ];64 assert.deepEqual(diff(aData1, aData4), aDiff, "diff between data 1 and 4");65 aDiff = [66 { index: 1, type: 'insert' },67 { index: 2, type: 'insert' },68 { index: 5, type: 'delete' },69 { index: 5, type: 'delete' }70 ];71 assert.deepEqual(diff(aData2, aData3), aDiff, "diff between data 2 and 3");72 aDiff = [73 { index: 1, type: 'delete' },74 { index: 1, type: 'delete' },75 { index: 3, type: 'insert' },76 { index: 4, type: 'insert' }77 ];78 assert.deepEqual(diff(aData2, aData4), aDiff, "diff between data 2 and 4");79 aDiff = [80 { index: 3, type: 'delete' },81 { index: 3, type: 'delete' },82 { index: 3, type: 'insert' },83 { index: 4, type: 'insert' }84 ];85 assert.deepEqual(diff(aData3, aData4), aDiff, "diff between data 3 and 4");86 aDiff = [87 { index: 0, type: 'delete' },88 { index: 0, type: 'delete' },89 { index: 3, type: 'insert' },90 { index: 4, type: 'insert' }91 ];92 assert.deepEqual(diff(aData1, aData5), aDiff, "diff between data 1 and 5");93 aDiff = [94 { index: 0, type: 'insert' },95 { index: 1, type: 'insert' },96 { index: 5, type: 'delete' },97 { index: 5, type: 'delete' }98 ];99 assert.deepEqual(diff(aData5, aData1), aDiff, "diff between data 5 and 1");100 aDiff = [101 { index: 0, type: 'insert' },102 { index: 1, type: 'insert' },103 { index: 2, type: 'insert' },104 { index: 3, type: 'insert' },105 { index: 5, type: 'delete' },106 { index: 5, type: 'delete' },107 { index: 5, type: 'delete' },108 { index: 5, type: 'delete' }109 ];110 assert.deepEqual(diff(aData1, aData10), aDiff, "diff between data 1 and 10");111 aDiff = [112 { index: 0, type: 'insert' },113 { index: 1, type: 'insert' },114 { index: 2, type: 'insert' },115 { index: 3, type: 'insert' },116 { index: 4, type: 'insert' }117 ];118 assert.deepEqual(diff(aData11, aData1), aDiff, "diff between data 1 and 11");119 aDiff = [120 { index: 0, type: 'delete' },121 { index: 0, type: 'delete' },122 { index: 0, type: 'delete' },123 { index: 0, type: 'delete' },124 { index: 0, type: 'delete' }125 ];126 assert.deepEqual(diff(aData1, aData11), aDiff, "diff between data 11 and 1");127 aDiff = [128 { index: 1, type: 'insert' },129 { index: 3, type: 'delete' },130 { index: 3, type: 'insert' },131 { index: 5, type: 'delete' }132 ];133 assert.deepEqual(diff(aData1, aData12), aDiff, "diff between data 1 and 12");134 aDiff = [135 { index: 0, type: 'insert' },136 { index: 1, type: 'delete' },137 { index: 1, type: 'delete' },138 { index: 2, type: 'insert' },139 { index: 3, type: 'insert' },140 { index: 4, type: 'insert' },141 { index: 5, type: 'insert' },142 { index: 6, type: 'insert' },143 { index: 7, type: 'insert' }144 ];145 assert.deepEqual(diff(aData6, aData9), aDiff, "diff between data 6 and 9");146 aDiff = [147 { index: 0, type: 'insert' },148 { index: 1, type: 'insert' },149 { index: 2, type: 'insert' },150 { index: 4, type: 'delete' },151 { index: 4, type: 'delete' },152 { index: 4, type: 'delete' }153 ];154 assert.deepEqual(diff(aData13, aData14), aDiff, "diff between data 13 and 14");155 aDiff = [156 { index: 0, type: 'delete' },157 { index: 0, type: 'delete' },158 { index: 1, type: 'delete' },159 { index: 1, type: 'delete' },160 { index: 1, type: 'delete' },161 { index: 1, type: 'delete' },162 { index: 1, type: 'delete' },163 { index: 1, type: 'delete' },164 { index: 1, type: 'delete' },165 { index: 1, type: 'delete' },166 { index: 1, type: 'delete' },167 { index: 1, type: 'delete' },168 { index: 1, type: 'delete' },169 { index: 1, type: 'delete' },170 { index: 1, type: 'delete' },171 { index: 1, type: 'delete' },172 { index: 2, type: 'delete' },173 { index: 2, type: 'delete' },174 { index: 2, type: 'delete' },175 { index: 2, type: 'delete' },176 { index: 2, type: 'delete' },177 { index: 2, type: 'delete' },178 { index: 2, type: 'delete' },179 { index: 2, type: 'delete' },180 { index: 2, type: 'delete' },181 { index: 2, type: 'delete' },182 { index: 2, type: 'insert' },183 { index: 3, type: 'insert' },184 { index: 4, type: 'insert' },185 { index: 5, type: 'insert' },186 { index: 6, type: 'insert' },187 { index: 7, type: 'insert' },188 { index: 8, type: 'insert' },189 { index: 9, type: 'insert' },190 { index: 10, type: 'insert' }191 ];192 assert.deepEqual(diff(aData15, aData16), aDiff, "diff between data 15 and 16");193 aDiff = [194 { index: 0, type: 'delete' },195 { index: 0, type: 'delete' },196 { index: 0, type: 'delete' },197 { index: 0, type: 'delete' },198 { index: 0, type: 'delete' },199 { index: 0, type: 'insert' },200 { index: 1, type: 'insert' },201 { index: 2, type: 'insert' },202 { index: 3, type: 'insert' },203 { index: 4, type: 'insert' }204 ];205 assert.deepEqual(diff(aData17, aData18), aDiff, "diff between data 17 and 18");206 aDiff = [207 { index: 4, type: 'delete' },208 { index: 4, type: 'insert' }209 ];210 assert.deepEqual(diff(aData19, aData20), aDiff, "diff between data 19 and 20");211 aDiff = [212 { index: 5, type: 'insert' }213 ];214 assert.deepEqual(diff(aData1, aData21), aDiff, "diff between data 1 and 21");215 aDiff = [216 { index: 0, type: 'delete' },217 { index: 0, type: 'delete' },218 { index: 0, type: 'delete' },219 { index: 0, type: 'delete' },220 { index: 0, type: 'insert' },221 { index: 1, type: 'insert' },222 { index: 3, type: 'delete' },223 { index: 3, type: 'delete' },224 { index: 3, type: 'delete' },225 { index: 3, type: 'delete' },226 { index: 3, type: 'delete' },227 { index: 3, type: 'insert' },228 { index: 4, type: 'insert' },229 { index: 5, type: 'insert' },230 { index: 6, type: 'insert' },231 { index: 7, type: 'insert' },232 { index: 8, type: 'insert' },233 { index: 9, type: 'insert' }234 ];235 assert.deepEqual(diff(aData22, aData23), aDiff, "diff between data 22 and 23");236 aDiff = [237 { index: 4, type: 'delete' },238 { index: 4, type: 'insert' },239 { index: 6, type: 'insert' }240 ];241 assert.deepEqual(diff(aData19, aData24), aDiff, "diff between data 19 and 24");242 });243 QUnit.test("random arrays", function(assert) {244 for (var t = 0; t < 100; t++) {245 var listA = [],246 listB = [],247 listACount = Math.floor(Math.random() * 101),248 listBCount = Math.floor(Math.random() * 101),249 aDiff;250 for (var a = 0; a < listACount; a++) {251 listA[a] = Math.floor(Math.random() * 101);252 }253 for (var b = 0; b < listBCount; b++) {254 listB[b] = Math.floor(Math.random() * 101);255 }256 aDiff = diff(listA, listB);257 for (var d = 0; d < aDiff.length; d++) {258 var oDiff = aDiff[d];259 if (oDiff.type === "insert") {260 listA.splice(oDiff.index, 0, listB[oDiff.index]);261 } else {262 listA.splice(oDiff.index, 1);263 }264 }265 assert.deepEqual(listA, listB, "random arrayDiff " + (t + 1));266 }267 });268 QUnit.test("arrays with undefined values", function(assert) {269 var a1 = [1, 2, 3, undefined],270 a2 = [1, undefined],271 aDiff = diff(a1, a2),272 aResult = [273 { index: 1, type: 'delete'},274 { index: 1, type: 'delete'}275 ];276 assert.deepEqual(aDiff, aResult, "diff must work with undefined values");277 });...
diff_parser_unittest.py
Source:diff_parser_unittest.py
...86 "Index: Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",87 "===================================================================\n",88 "--- Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",89 "+++ Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",90 "@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):\n",91 ]92 self.assertEqual(diff_parser.get_diff_converter(svn_diff_lines), diff_parser.svn_diff_to_svn_diff)93 self.assertEqual(diff_parser.get_diff_converter(comment_lines + svn_diff_lines), diff_parser.svn_diff_to_svn_diff)94 self.assertEqual(diff_parser.get_diff_converter(revision_lines + svn_diff_lines), diff_parser.svn_diff_to_svn_diff)95 git_diff_lines = [96 "diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",97 "index 3c5b45b..0197ead 100644\n",98 "--- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",99 "+++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n",100 "@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):\n",101 ]102 self.assertEqual(diff_parser.get_diff_converter(git_diff_lines), diff_parser.git_diff_to_svn_diff)103 self.assertEqual(diff_parser.get_diff_converter(comment_lines + git_diff_lines), diff_parser.git_diff_to_svn_diff)104 self.assertEqual(diff_parser.get_diff_converter(revision_lines + git_diff_lines), diff_parser.git_diff_to_svn_diff)105 def test_git_mnemonicprefix(self):106 p = re.compile(r' ([a|b])/')107 prefixes = [108 { 'a' : 'i', 'b' : 'w' }, # git-diff (compares the (i)ndex and the (w)ork tree)109 { 'a' : 'c', 'b' : 'w' }, # git-diff HEAD (compares a (c)ommit and the (w)ork tree)110 { 'a' : 'c', 'b' : 'i' }, # git diff --cached (compares a (c)ommit and the (i)ndex)111 { 'a' : 'o', 'b' : 'w' }, # git-diff HEAD:file1 file2 (compares an (o)bject and a (w)ork tree entity)112 { 'a' : '1', 'b' : '2' }, # git diff --no-index a b (compares two non-git things (1) and (2))113 ]114 for prefix in prefixes:115 patch = p.sub(lambda x: " %s/" % prefix[x.group(1)], DIFF_TEST_DATA)116 self.test_diff_parser(diff_parser.DiffParser(patch.splitlines()))117 def test_git_diff_to_svn_diff(self):118 output = """\119Index: Tools/Scripts/webkitpy/common/checkout/diff_parser.py120===================================================================121--- Tools/Scripts/webkitpy/common/checkout/diff_parser.py122+++ Tools/Scripts/webkitpy/common/checkout/diff_parser.py123@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):124 A125 B126 C127+D128 E129 F130"""131 inputfmt = StringIO.StringIO("""\132diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py133index 2ed552c4555db72df16b212547f2c125ae301a04..72870482000c0dba64ce4300ed782c03ee79b74f 100644134--- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py135+++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py136@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):137 A138 B139 C140+D141 E142 F143""")144 shortfmt = StringIO.StringIO("""\145diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py146index b48b162..f300960 100644147--- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py148+++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py149@@ -59,6 +59,7 @@ def git_diff_to_svn_diff(line):150 A151 B152 C153+D154 E155 F156""")157 self.assertMultiLineEqual(output, ''.join(diff_parser.git_diff_to_svn_diff(x) for x in shortfmt.readlines()))...
index.js
Source:index.js
1(function () {2 var settings = allure.getPluginSettings('screen-diff', {diffType: 'diff'});3 function renderImage(src) {4 return '<div class="screen-diff__container">' +5 '<img class="screen-diff__image" src="data/attachments/' + src + '">' +6 '</div>';7 }8 function renderDiffContent(type, data) {9 function findImage(name) {10 if (data.testStage && data.testStage.attachments) {11 return data.testStage.attachments.filter(function (attachment) {12 return attachment.name === name;13 })[0];14 }15 return null;16 }17 var diffImage = findImage('diff');18 var actualImage = findImage('actual');19 var expectedImage = findImage('expected');20 if (!diffImage && !actualImage && !expectedImage) {21 return '<span>Diff, actual and expected image have not been provided.</span>';22 }23 if (type === 'diff') {24 if (!diffImage) {25 return renderImage(actualImage.source);26 }27 return renderImage(diffImage.source);28 }29 if (type === 'overlay') {30 return '<div class="screen-diff__overlay screen-diff__container">' +31 '<img class="screen-diff__image" src="data/attachments/' + expectedImage.source + '">' +32 '<div class="screen-diff__image-over">' +33 '<img class="screen-diff__image" src="data/attachments/' + actualImage.source + '">' +34 '</div>' +35 '</div>';36 }37 }38 var ScreenDiffView = Backbone.Marionette.View.extend({39 className: 'pane__section',40 events: {41 'click [name="screen-diff-type"]': 'onDiffTypeChange',42 'mousemove .screen-diff__overlay': 'onOverlayMove'43 },44 templateContext: function () {45 return {46 diffType: settings.get('diffType')47 }48 },49 template: function (data) {50 var testType = data.labels.filter(function (label) {51 return label.name === 'testType'52 })[0];53 if (!testType || testType.value !== 'screenshotDiff') {54 return '';55 }56 return '<h3 class="pane__section-title">Screen Diff</h3>' +57 '<div class="screen-diff__content">' +58 '<div class="screen-diff__switchers">' +59 '<label><input type="radio" name="screen-diff-type" value="diff"> Show diff</label>' +60 '<label><input type="radio" name="screen-diff-type" value="overlay"> Show overlay</label>' +61 '</div>' +62 renderDiffContent(data.diffType, data) +63 '</div>';64 },65 adjustImageSize: function (event) {66 var overImage = this.$(event.target);67 overImage.width(overImage.width());68 },69 onRender: function () {70 const diffType = settings.get('diffType');71 this.$('[name="screen-diff-type"][value="' + diffType + '"]').prop('checked', true);72 if (diffType === 'overlay') {73 this.$('.screen-diff__image-over img').on('load', this.adjustImageSize.bind(this));74 }75 },76 onOverlayMove: function (event) {77 var pageX = event.pageX;78 var containerScroll = this.$('.screen-diff__container').scrollLeft();79 var elementX = event.currentTarget.getBoundingClientRect().left;80 var delta = pageX - elementX + containerScroll;81 this.$('.screen-diff__image-over').width(delta);82 },83 onDiffTypeChange: function (event) {84 settings.save('diffType', event.target.value);85 this.render();86 }87 });88 allure.api.addTestResultBlock(ScreenDiffView, {position: 'before'});...
template-diff.js
Source:template-diff.js
1/*2 * Template Diff plugin3 *4 * Data attributes:5 * - data-plugin="template-diff" - enables the plugin on an element6 *7 * JavaScript API:8 * $('pre').templateDiff({ option: 'value' })9 *10 * Dependences:11 * - jsdiff (diff.js)12 */13+function ($) { "use strict";14 // TEMPALTE DIFF CLASS DEFINITION15 // ============================16 var TemplateDiff = function(element, options) {17 this.options = options18 this.$el = $(element)19 // Init20 this.init()21 }22 TemplateDiff.DEFAULTS = {23 oldFieldName: null,24 newFieldName: null,25 contentTag: '',26 diffType: 'lines' // chars, words, lines27 }28 TemplateDiff.prototype.init = function() {29 var30 oldValue = $('[data-field-name="'+this.options.oldFieldName+'"] .form-control '+this.options.contentTag).html(),31 newValue = $('[data-field-name="'+this.options.newFieldName+'"] .form-control '+this.options.contentTag).html()32 oldValue = $('<div />').html(oldValue).text()33 newValue = $('<div />').html(newValue).text()34 this.diffStrings(oldValue, newValue)35 }36 TemplateDiff.prototype.diffStrings = function(oldValue, newValue) {37 var result = this.$el.get(0)38 var diffType = 'diff' + this.options.diffType[0].toUpperCase() + this.options.diffType.slice(1)39 var diff = JsDiff[diffType](oldValue, newValue)40 var fragment = document.createDocumentFragment();41 for (var i=0; i < diff.length; i++) {42 if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {43 var swap = diff[i];44 diff[i] = diff[i + 1];45 diff[i + 1] = swap;46 }47 var node;48 if (diff[i].removed) {49 node = document.createElement('del');50 node.appendChild(document.createTextNode(diff[i].value));51 }52 else if (diff[i].added) {53 node = document.createElement('ins');54 node.appendChild(document.createTextNode(diff[i].value));55 }56 else {57 node = document.createTextNode(diff[i].value);58 }59 fragment.appendChild(node);60 }61 result.textContent = '';62 result.appendChild(fragment);63 }64 // TEMPALTE DIFF PLUGIN DEFINITION65 // ============================66 var old = $.fn.templateDiff67 $.fn.templateDiff = function (option) {68 var args = Array.prototype.slice.call(arguments, 1), result69 this.each(function () {70 var $this = $(this)71 var data = $this.data('oc.example')72 var options = $.extend({}, TemplateDiff.DEFAULTS, $this.data(), typeof option == 'object' && option)73 if (!data) $this.data('oc.example', (data = new TemplateDiff(this, options)))74 if (typeof option == 'string') result = data[option].apply(data, args)75 if (typeof result != 'undefined') return false76 })77 78 return result ? result : this79 }80 $.fn.templateDiff.Constructor = TemplateDiff81 // TEMPALTE DIFF NO CONFLICT82 // =================83 $.fn.templateDiff.noConflict = function () {84 $.fn.templateDiff = old85 return this86 }87 // TEMPALTE DIFF DATA-API88 // ===============89 $(document).render(function () {90 $('[data-plugin="template-diff"]').templateDiff()91 });...
Using AI Code Generation
1const { diff } = require('jest-diff');2const object1 = {3};4const object2 = {5};6const object3 = {7};8console.log(diff(object1, object2));9console.log(diff(object1, object3));10const { toMatchDiffSnapshot } = require('jest-diff-snapshot');11expect.extend({ toMatchDiffSnapshot });12test('object comparison', () => {13 const object1 = {14 };15 const object2 = {16 };17 const object3 = {18 };19 expect(object1).toMatchDiffSnapshot(object2);20 expect(object1).toMatchDiffSnapshot(object3);21});
Using AI Code Generation
1const { diff } = require("jest-diff");2const { toMatchDiffSnapshot } = require("snapshot-diff");3expect.extend({ toMatchDiffSnapshot });4const { diff } = require("jest-diff");5const { toMatchDiffSnapshot } = require("snapshot-diff");6expect.extend({ toMatchDiffSnapshot });7const object1 = {8};9const object2 = {10};11const { diff } = require("jest-diff");12const { toMatchDiffSnapshot } = require("snapshot-diff");13expect.extend({ toMatchDiffSnapshot });14const object1 = {15};16const object2 = {17};18const { diff } = require("jest-diff");19const { toMatchDiffSnapshot } = require("snapshot-diff");20expect.extend({ toMatchDiffSnapshot });21const object1 = {22};23const object2 = {24};25const { diff } = require("jest-diff");26const { toMatchDiffSnapshot } = require("snapshot-diff");27expect.extend({ toMatchDiffSnapshot });28const object1 = {29};30const object2 = {31};32const { diff } = require("jest-diff");33const { toMatchDiffSnapshot } = require("snapshot-diff");34expect.extend({ toMatchDiffSnapshot });35const object1 = {36};37const object2 = {38};
Using AI Code Generation
1const diff = require('jest-diff');2test('test diff method of jest-extended', () => {3 const obj1 = {4 c: {5 },6 };7 const obj2 = {8 c: {9 },10 };11 const result = diff(obj1, obj2);12 console.log(result);13});14const diff = require('jest-diff').default;15test('test diff method of jest-diff', () => {16 const obj1 = {17 c: {18 },19 };20 const obj2 = {21 c: {22 },23 };24 const result = diff(obj1, obj2);25 console.log(result);26});27const { diff } = require('jest-diff');28test('test diff method of jest-diff', () => {29 const obj1 = {30 c: {31 },32 };33 const obj2 = {34 c: {35 },36 };37 const result = diff(obj1, obj2);38 console.log(result);39});
Using AI Code Generation
1expect.extend({ toBeWithinRange });2expect(10).toBeWithinRange(9, 11);3expect.extend({ toBeArray });4expect([1, 2, 3]).toBeArray();5expect.extend({ toBeBoolean });6expect(true).toBeBoolean();7expect.extend({ toBeDate });8expect(new Date()).toBeDate();9expect.extend({ toBeEmpty });10expect([]).toBeEmpty();11expect.extend({ toBeFunction });12expect(() => {}).toBeFunction();13expect.extend({ toBeObject });14expect({}).toBeObject();15expect.extend({ toBeString });16expect('foo').toBeString();17expect.extend({ toBeNumber });18expect(1).toBeNumber();19expect.extend({ toBeTrue });20expect(true).toBeTrue();21expect.extend({ toBeFalse });22expect(false).toBeFalse();23expect.extend({ toBeNaN });24expect(NaN).toBeNaN();25expect.extend({ toBeType });26expect('foo').toBeType('string');27expect.extend({ toBeUndefined });28expect(undefined).toBeUndefined();29expect.extend({ toBeInstanceOf });30expect(new Error()).toBeInstanceOf(Error);31expect.extend({ toBeEmptyArray });32expect([]).toBeEmptyArray();33expect.extend({ toBeEmptyObject });34expect({}).toBeEmptyObject();35expect.extend({ toBeEmptyString });36expect('').toBeEmptyString();
Using AI Code Generation
1const {diff} = require('jest-diff');2const {toStrictEqual} = require('jest-extended');3describe('test', () => {4 it('test', () => {5 const obj1 = {a: 1, b: 2};6 const obj2 = {a: 1, b: 2};7 expect(obj1).toStrictEqual(obj2);8 expect(diff(obj1, obj2)).toBe(undefined);9 });10});11 √ test (3ms)
Using AI Code Generation
1const diff = require('jest-diff');2const { toMatchDiffSnapshot } = require('jest-diff-snapshot');3expect.extend({ toMatchDiffSnapshot });4test('compare two objects', () => {5 const obj1 = { a: 1, b: 2, c: 3 };6 const obj2 = { a: 1, b: 2, c: 4 };7 const result = diff(obj1, obj2);8 expect(result).toMatchDiffSnapshot();9});10Object {11 "added": Object {12 },13 "common": Object {14 },15 "deleted": Object {16 },17}18`;19 ✓ compare two objects (3ms)20 Object {21 "added": Object {22 },23 "common": Object {24 },25 "deleted": Object {26 },27 }
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!