public void Align_WithNullElements() { var collection1 = new[] { "Line 1", "Line 2", null, "Line 3", "Line 4", }; var collection2 = new[] { "Line 1", null, "Line 2", "Line 4", }; DiffSection[] sections = Diff.CalculateSections(collection1, collection2).ToArray(); var elements = Diff.AlignElements(collection1, collection2, sections, new StringSimilarityDiffElementAligner()); CollectionAssert.AreEqual(new[] { new DiffElement <string>("Line 1", "Line 1", DiffOperation.Match), new DiffElement <string>(Option <string> .None, null, DiffOperation.Insert), new DiffElement <string>("Line 2", "Line 2", DiffOperation.Match), new DiffElement <string>(null, Option <string> .None, DiffOperation.Delete), new DiffElement <string>("Line 3", Option <string> .None, DiffOperation.Delete), new DiffElement <string>("Line 4", "Line 4", DiffOperation.Match), }, elements); }
private IDisposable BindFromSource <TModel>(TModel model, Expression <Func <TModel, SelectionData> > propertyExpr, Func <IDisposable> startTransaction) { return(model.WhenAnyValue(propertyExpr) .Buffer(2, 1) .Where(b => b.Count == 2) .Select(b => { var previous = b[0].ObjectIds.ToList(); var current = b[1].ObjectIds.ToList(); var sections = Diff.CalculateSections(previous, current); var alignedElements = Diff .AlignElements(previous, current, sections, new BasicInsertDeleteDiffElementAligner <SelectionData.ObjectId>()) .ToList(); var oldObjectIds = alignedElements .Where(e => e.Operation == DiffOperation.Delete || e.Operation == DiffOperation.Replace) .Select(e => e.ElementFromCollection1.Value); var newObjectIds = alignedElements .Where(e => e.Operation == DiffOperation.Insert || e.Operation == DiffOperation.Replace) .Select(e => e.ElementFromCollection2.Value); return new { oldSelectionData = b[0], oldObjectIds, newSelectionData = b[1], newObjectIds }; }) .Subscribe(o => { using (startTransaction()) { ModelDoc.ClearSelection(o.oldSelectionData.WithObjectIds(o.oldObjectIds)); ModelDoc.AddSelection(o.newSelectionData.WithObjectIds(o.newObjectIds)); } })); }
public void BasicReplaceInsertDeleteDiffElementAlignerTestCases(string s1, string s2, string expected) { var sections = Diff.CalculateSections(s1.ToCharArray(), s2.ToCharArray()); var elements = Diff.AlignElements(s1.ToCharArray(), s2.ToCharArray(), sections, new BasicReplaceInsertDeleteDiffElementAligner <char>()); var output = GetElementOperationsAsAString(elements); Assert.That(output, Is.EqualTo(expected)); }
public void AlignElements_NullAligner_ThrowsArgumentNullException() { IList <int> collection1 = new int[0]; IList <int> collection2 = new int[0]; IEnumerable <DiffSection> diffSections = new DiffSection[0]; IDiffElementAligner <int> aligner = null; Assert.Throws <ArgumentNullException>(() => Diff.AlignElements(collection1, collection2, diffSections, aligner)); }
public static bool Compare(string input1, string input2, StringWriter diff, Func <string, string> normalizeLine, string[] definedSymbols = null) { var collection1 = NormalizeAndSplitCode(input1, definedSymbols ?? new string[0]); var collection2 = NormalizeAndSplitCode(input2, definedSymbols ?? new string[0]); var diffSections = DiffLib.Diff.CalculateSections( collection1, collection2, new CodeLineEqualityComparer(normalizeLine) ); var alignedDiff = Diff.AlignElements(collection1, collection2, diffSections, new StringSimilarityDiffElementAligner()); bool result = true, ignoreChange; int line1 = 0, line2 = 0; foreach (var change in alignedDiff) { switch (change.Operation) { case DiffOperation.Match: diff.Write("{0,4} {1,4} ", ++line1, ++line2); diff.Write(" "); diff.WriteLine(change.ElementFromCollection1.Value); break; case DiffOperation.Insert: diff.Write(" {1,4} ", line1, ++line2); result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection2.Value); diff.Write(ignoreChange ? " " : " + "); diff.WriteLine(change.ElementFromCollection2.Value); break; case DiffOperation.Delete: diff.Write("{0,4} ", ++line1, line2); result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection1.Value); diff.Write(ignoreChange ? " " : " - "); diff.WriteLine(change.ElementFromCollection1.Value); break; case DiffOperation.Modify: case DiffOperation.Replace: diff.Write("{0,4} ", ++line1, line2); result = false; diff.Write("(-) "); diff.WriteLine(change.ElementFromCollection1.Value); diff.Write(" {1,4} ", line1, ++line2); diff.Write("(+) "); diff.WriteLine(change.ElementFromCollection2.Value); break; } } return(result); }
public static IObservable <List <DiffElement <T> > > ChangesObservable <T>(this ICompositeList <T> source, IEqualityComparer <T> comparer = null) { return(source .Items .StartWith(ImmutableList <T> .Empty) .Buffer(2, 1).Where(b => b.Count == 2) .Select(b => { var sections = Diff.CalculateSections(b[0], b[1], comparer); var alignment = Diff.AlignElements (b[0], b[1], sections, new BasicReplaceInsertDeleteDiffElementAligner <T>()); return alignment.ToList(); })); }
public void ElementSimilarityDiffElementAlignerTestCases(string s1, string s2, string expected) { double aligner(char element1, char element2) { if (element1 == element2) { return(1.0); } if (char.ToUpper(element1) == char.ToUpper(element2)) { return(0.75); } return(0.0); } var sections = Diff.CalculateSections(s1.ToCharArray(), s2.ToCharArray()); var elements = Diff.AlignElements(s1.ToCharArray(), s2.ToCharArray(), sections, new ElementSimilarityDiffElementAligner <char>(aligner)); var output = GetElementOperationsAsAString(elements); Assert.That(output, Is.EqualTo(expected)); }
public static bool Compare(string input1, string input2, StringWriter diff, Func <string, string> normalizeLine, string[] definedSymbols = null) { var collection1 = NormalizeAndSplitCode(input1, definedSymbols ?? new string[0]); var collection2 = NormalizeAndSplitCode(input2, definedSymbols ?? new string[0]); var diffSections = DiffLib.Diff.CalculateSections( collection1, collection2, new CodeLineEqualityComparer(normalizeLine) ); var alignedDiff = Diff.AlignElements(collection1, collection2, diffSections, new StringSimilarityDiffElementAligner()); bool result = true; int line1 = 0, line2 = 0; const int contextSize = 10; int consecutiveMatches = contextSize; var hiddenMatches = new List <string>(); foreach (var change in alignedDiff) { switch (change.Operation) { case DiffOperation.Match: AppendMatch($"{++line1,4} {++line2,4} ", change.ElementFromCollection1.Value); break; case DiffOperation.Insert: string pos = $" {++line2,4} "; if (ShouldIgnoreChange(change.ElementFromCollection2.Value)) { AppendMatch(pos, change.ElementFromCollection2.Value); } else { AppendDelta(pos, " + ", change.ElementFromCollection2.Value); result = false; } break; case DiffOperation.Delete: pos = $"{++line1,4} "; if (ShouldIgnoreChange(change.ElementFromCollection1.Value)) { AppendMatch(pos, change.ElementFromCollection1.Value); } else { AppendDelta(pos, " - ", change.ElementFromCollection1.Value); result = false; } break; case DiffOperation.Modify: case DiffOperation.Replace: AppendDelta($"{++line1,4} ", "(-)", change.ElementFromCollection1.Value); AppendDelta($" {++line2,4} ", "(+)", change.ElementFromCollection2.Value); result = false; break; } } if (hiddenMatches.Count > 0) { diff.WriteLine(" ..."); } return(result); void AppendMatch(string pos, string code) { consecutiveMatches++; if (consecutiveMatches > contextSize) { // hide this match hiddenMatches.Add(pos + " " + code); } else { diff.WriteLine(pos + " " + code); } } void AppendDelta(string pos, string changeType, string code) { consecutiveMatches = 0; if (hiddenMatches.Count > contextSize) { diff.WriteLine(" ..."); } for (int i = Math.Max(0, hiddenMatches.Count - contextSize); i < hiddenMatches.Count; i++) { diff.WriteLine(hiddenMatches[i]); } hiddenMatches.Clear(); diff.WriteLine(pos + changeType + " " + code); } }
public static bool Compare(string input1, string input2, StringWriter diff) { List <string> input1List = NormalizeAndSplitCode(input1).ToList(); List <string> input2List = NormalizeAndSplitCode(input2).ToList(); IEnumerable <DiffSection> diffSections = Diff.CalculateSections(input1List, input2List, new CodeLineEqualityComparer()); IEnumerable <DiffElement <string> > diffElements = Diff.AlignElements( input1List, input2List, diffSections, new StringSimilarityDiffElementAligner()); bool result = true; int line1 = 0, line2 = 0; foreach (DiffElement <string> change in diffElements) { bool ignoreChange; switch (change.Operation) { case DiffOperation.Match: diff.Write("{0,4} {1,4} ", ++line1, ++line2); diff.Write(" "); diff.WriteLine(change.ElementFromCollection1); break; case DiffOperation.Insert: diff.Write(" {1,4} ", line1, ++line2); result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection2.Value); diff.Write(ignoreChange ? " " : " + "); diff.WriteLine(change.ElementFromCollection2); break; case DiffOperation.Delete: diff.Write("{0,4} ", ++line1, line2); result &= ignoreChange = ShouldIgnoreChange(change.ElementFromCollection1.Value); diff.Write(ignoreChange ? " " : " - "); diff.WriteLine(change.ElementFromCollection1); break; case DiffOperation.Replace: diff.Write("{0,4} ", ++line1, line2); result = false; diff.Write("(-) "); diff.WriteLine(change.ElementFromCollection1); diff.Write(" {1,4} ", line1, ++line2); diff.Write("(+) "); diff.WriteLine(change.ElementFromCollection2); break; case DiffOperation.Modify: diff.Write("{0,4} ", ++line1, line2); result = false; diff.Write("(-) "); diff.WriteLine(change.ElementFromCollection1); diff.Write(" {1,4} ", line1, ++line2); diff.Write("(*) "); diff.WriteLine(change.ElementFromCollection2); break; default: throw new ArgumentOutOfRangeException(); } } return(result); }