public void Apply_Sequence() { // Set original and expected string original_text = "hello"; string expected_text = "eblol"; // Encode the original UTF-8 text to byte array byte[] original_bytes = Encoding.UTF8.GetBytes(original_text); // Create the edit script to patch original to expected EditScript script = new EditScript(); script.Add(new Replacement(2, 98)); script.Add(new Deletion(0)); script.Add(new Insertion(4, 108)); // Create the Patchup patch from the edit script Patch patch = new Patch { EditScript = script }; // Apply the Patchup patch to the data byte[] patched_data = patch.Apply(original_bytes); // Decode the patched byte array back to UTF-8 text string patched_text = Encoding.UTF8.GetString(patched_data); Assert.Equal(expected_text, patched_text); }
/// <summary> /// Turns Myers match points to final edit script /// </summary> /// <param name="n">Length of A sequence</param> /// <param name="m">Length of B sequence</param> /// <param name="matchPoints">Match points</param> /// <returns>Final edit script</returns> private EditScript ConvertMatchPointsToEditScript(int n, int m, ICollection <Point2D <int> > matchPoints) { // The Execute method already has an assertion that the number of MatchPoints // equals the LCS length, so we can use it to calculate similarity, but we must do // it before we add a fictitious match point below. var similarity = GetSimilarity(n, m, matchPoints.Count); var script = new EditScript(similarity); var currentX = 1; var currentY = 1; // Add a fictitious match point at (N+1, M+1) so we're guaranteed to // pick up all edits with a single loop. matchPoints.Add(new Point2D <int>(n + 1, m + 1)); // NOTE: When we create new Edit instances, we'll store iCurrX and iCurrY // minus 1 because we want to convert them back to 0-based indexes for // the user. The user shouldn't have to know that internally we use any // 1-based types. foreach (var point in matchPoints) { var matchX = point.X; var matchY = point.Y; // A one-to-one grouping of inserts and deletes will be considered a change. if (_supportChangeEditType && currentX < matchX && currentY < matchY) { var changeLength = Math.Min(matchX - currentX, matchY - currentY); script.Add(new Edit(TextEditType.Change, currentX - 1, currentY - 1, changeLength)); currentX += changeLength; currentY += changeLength; } if (currentX < matchX) { script.Add(new Edit(TextEditType.Delete, currentX - 1, currentY - 1, matchX - currentX)); } if (currentY < matchY) { script.Add(new Edit(TextEditType.Insert, currentX - 1, currentY - 1, matchY - currentY)); } currentX = matchX + 1; currentY = matchY + 1; } return(script); }
public static EditScript SingleThreaded(byte[] original, byte[] target) { var script = new EditScript(); var stack = new Stack <Bounds>(); stack.Push(null); while (stack.Count > 0) { var bounds = stack.Pop(); var result = Snake.Middle(original, target, bounds); if (result.Edit != null) { script.Add(result.Edit); } // Push lower bounds after upper bounds to the stack so that lower bounds is processed first and the edit script is computed in order if (result.Upper != null) { stack.Push(result.Upper); } if (result.Lower != null) { stack.Push(result.Lower); } } return(script); }
public void Apply_Replacement() { string original_text = "hello"; string expected_text = "bello"; // Convert byte[] original_bytes = Encoding.UTF8.GetBytes(original_text); EditScript script = new EditScript(); script.Add(new Replacement(0, 98)); Patch patch = new Patch { EditScript = script }; byte[] patched_data = patch.Apply(original_bytes); string patched_text = Encoding.UTF8.GetString(patched_data); Assert.Equal(expected_text, patched_text); }